June 18, 2006

For developers - here is a c code for sudoku

Source: http://www.setbb.com/phpbb/

// speed-optimized for hard 16*16s , new trick: remember how good
// column-choices were ! (see lines with a ~)

#include stdio.h
#include time.h
#include stdio.h
#include sys/time.h

#define N 4 // 16*16-sudoku
#define N2 N*N
#define N4 N2*N2
#define MWC ( (zr=36969*(zr&65535)+(zr>>16)) ^ (wr=18000*(wr&65535)+(wr>>16)) )
int A[N4 + 9], Ur[N2 * N4 + 1], Uc[4 * N4 + 1], V[N2 * N4 + 1];
int Rows[4 * N4 + 1], Cols[N2 * N4 + 1], Row[4 * N4 + 1][N2 + 1],
Col[N2 * N4 + 1][5];
int C[N4 + 1], I[N4 + 1], Node[N4 + 1], Two[N4 * 4 + 9], C0[N4 * 4 + 9], P[N4 + 9];
int M1[N4 + 9][4 * N4 + 9], N1[N4 + 9][4 * N4 + 9], Z1[N4 + 9][4 * N4 + 9]; //~
int s1, i1, t1, i4, c0, m0, m1, try, i, j, k, l, r, r1, c, c1, c2, n = N4 * N2, m =
4 * N4, x, y, s;
int sam, samples, smax, min, clues, nodes, guesses, solutions;
unsigned zr = 362436069, wr = 521288629;
char L[18] = ".123456789ABCDEFG";
FILE *file;

int solve (int);
int reduce (int);
int unreduce (int);

int main (int argc, char *argv[])
{
clock ();
//These are for out rancom number x
unsigned int seed;
struct timeval tv;

if (argc <>
m5:printf ("\nusage:suexg16f samples \n\n");
printf ("generates samples sudokus\n");
exit (1);
}
gettimeofday (&tv, 0);
x = tv.tv_sec + tv.tv_usec;
zr += x;
wr ^= x;
sscanf (argv[1], "%i", &samples);

for (i = 1; i <= m; i++) {
j = 1;
while (j <>
j += j;
Two[i] = j - 1;
}

r = 0;
k = N;
l = N2;
for (x = 1; x <= N2; x++)
for (y = 1; y <= N2; y++)
for (s = 1; s <= N2; s++) {
r++;
Cols[r] = 4;
Col[r][1] = x * N2 - N2 + y;
Col[r][2] = (k * ((x - 1) / k) + (y - 1) / k) * l + s + N4;
Col[r][3] = x * N2 - N2 + s + N4 * 2;
Col[r][4] = y * N2 - N2 + s + N4 * 3;
}
for (i = 1; i <= m; i++)
Rows[i] = 0;
for (r = 1; r <= n; r++)
for (i = 1; i <= Cols[r]; i++) {
c = Col[r][i];
Rows[c]++;
Row[c][Rows[c]] = r;
}

for (sam = 1; sam <= samples; sam++) {
m0:for (i = 1; i <= N4; i++)
A[i] = 0;
solve (1);

for (i = 1; i <= N4; i++) {
mr4:x = MWC & 255;
if (x >= i)
goto mr4;
x++;
P[i] = P[x];
P[x] = i;
}
for (i1 = 1; i1 <= N4; i1++)
if (A[P[i1]]) {
s1 = A[P[i1]];
A[P[i1]] = 0;
if (solve (2) > 1)
A[P[i1]] = s1;
}

if ((file = fopen ("sudoku.16", "at")) == NULL) {
fclose (file);
printf ("\nfile-error\n\n");
exit (1);
}
for (i = 1; i <= N4; i++)
fprintf (file, "%c", L[A[i]]);
fprintf (file, "\n");
fclose (file);

for (i = 1; i <= N4; i++)
printf ("%c", L[A[i]]);
printf ("\n");
}
printf ("%i sudokus generated in %i/%isec.\n", samples, clock (), CLOCKS_PER_SEC);

return 0;
}

int solve (int smax)
{
for (i = 0; i <= N4 >> 4; i++)
for (j = 1; j <= m; j++) {
N1[i][j] = 0;
Z1[i][j] = 0;
} //~
for (i = 0; i <= n; i++)
Ur[i] = 0;
for (i = 0; i <= m; i++)
Uc[i] = 0;
clues = 0;
for (x = 1; x <= N2; x++)
for (y = 1; y <= N2; y++)
if (A[x * N2 - N2 + y]) {
clues++;
r = x * N4 - N4 + y * N2 - N2 + A[x * N2 - N2 + y];
for (j = 1; j <= Cols[r]; j++) {
c1 = Col[r][j];
if (Uc[c1])
return -1;
Uc[c1]++;
for (k = 1; k <= Rows[c1]; k++) {
r1 = Row[c1][k];
Ur[r1]++;
}
}
}
for (c = 1; c <= m; c++) {
V[c] = 0;
for (r = 1; r <= Rows[c]; r++)
if (Ur[Row[c][r]] == 0)
V[c]++;
}

m0 = 0;
m1 = 0;
guesses = 0;
i = clues;
solutions = 0;
m2:i++;
I[i] = 0;
min = n + 1;
if (i > N4 || m0)
goto m4;
if (m1) {
C[i] = m1;
goto m3;
}

c0 = 0;
for (c = 1; c <= m; c++)
if (!Uc[c]) {
if (V[c] <= min) {
c0++;
C0[c0] = c;
}
if (V[c] <>
min = V[c];
c0 = 1;
C[i] = c;
C0[c0] = c;
if (min <>
goto m3;
}
}
if (min > 1)
guesses++;

m2a:c1 = MWC & Two[c0];
if (c1 >= c0)
goto m2a;
c1++;
C[i] = C0[c1];

min = 999999;
i4 = i >> 4;
for (j = c1; j <= c0; j++) {
c = C0[j];
if (N1[i4][c] <>
min = N1[i4][c] / Z1[i4][c];
C[i] = c;
}
} //~
for (j = 1; j <>
c = C0[j];
if (N1[i4][c] <>
min = N1[i4][c] / Z1[i4][c];
C[i] = c;
}
} //~

m3:c = C[i];
I[i]++;
if (I[i] > Rows[c])
goto m4;
r = Row[c][I[i]];
if (Ur[r])
goto m3;
m0 = 0;
m1 = 0;
if (smax == 1) {
j = N2;
k = N4;
x = (r - 1) / k + 1;
y = ((r - 1) % k) / j + 1;
s = (r - 1) % j + 1;
A[x * N2 - N2 + y] = s;
}
for (j = 1; j <= Cols[r]; j++) {
c1 = Col[r][j];
Uc[c1]++;
}
for (j = 1; j <= Cols[r]; j++)
reduce (Col[r][j]);
Node[i]++;
nodes++;
M1[i][c] = nodes; //~ remember nodes
if (i == N4) {
solutions++;
if (smax == 1)
return 1;
}
if (solutions > 1)
return 2;
goto m2;
m4:c = C[i];
N1[i >> 4][c] += nodes - M1[i][c];
Z1[i >> 4][c]++; //~ column-statistics
i--;
c = C[i];
r = Row[c][I[i]];
for (j = 1; j <= Cols[r]; j++)
unreduce (Col[r][j]);
if (i > clues)
goto m3;
return solutions;
}

int reduce (int c)
{ // deletes c and N[c], updates V[],m0,m1
int r, c2, k, l;

for (k = 1; k <= Rows[c]; k++) {
r = Row[c][k];
Ur[r]++;
if (Ur[r] == 1)
for (l = 1; l <= Cols[r]; l++) {
c2 = Col[r][l];
V[c2]--;
if (Uc[c2] + V[c2] <>
m0 = c2;
if (Uc[c2] == 0 && V[c2] <>
m1 = c2;
}
}
}

int unreduce (int c)
{
int r, c2, k, l;

Uc[c]--;
for (k = 1; k <= Rows[c]; k++) {
r = Row[c][k];
Ur[r]--;
if (Ur[r] == 0)
for (l = 1; l <= Cols[r]; l++) {
c2 = Col[r][l];
V[c2]++;
}
}
}

No comments: