Newsgroup: it.comp.lang.c
Titolo: sudoku solver in meno di 600 caratteri

Oggi mi sono divertito a fare questo:
http://web.math.unifi.it/users/paolini/src/sudoku/
Di seguito il codice. Ho cercato di non sprecare caratteri, ma dovrebbe 
ancora essere leggibile...
#include <stdio.h>
int s[81], m[82], k, i;
int f() {
   for (i=0;i<81;++i) {
     if (i==k || s[i]==0) continue;
     if (i%9==k%9 || i/9==k/9 ||
	((i/3)%3==(k/3)%3 && (i/3/9==k/3/9)))
       if (s[i]==s[k]) return 0;
   }
   return 1;
}
int main() {
   for (i=0;i<81;++i) {
     scanf("%d",&m[i]);
     s[i]=m[i];
   }
   for(;;) {
     s[k]++;
     if (s[k]<=9 && f()) {
       if (k==80) {
	for (i=0;i<81;++i) {
	  printf("%d ",s[i]);
	  if (i%9>7) printf("\n");
	}
       } else while (m[++k]!=0);
     } else {
       if (s[k]>9) {
	s[k]=m[k];
	do if (0==k--) return 0;
	while(m[k]!=0);
       }
     }
   }
}
$ cat grid1
0 5 0 0 6 0 0 0 1
0 0 4 8 0 0 0 7 0
8 0 0 0 0 0 0 5 2
2 0 0 0 5 7 0 3 0
0 0 0 0 0 0 0 0 0
0 3 0 6 9 0 0 0 5
7 9 0 0 0 0 0 0 8
0 1 0 0 0 6 5 0 0
5 0 0 0 3 0 0 6 0
$ ./sudoku < grid1
9 5 3 7 6 2 8 4 1
6 2 4 8 1 5 9 7 3
8 7 1 3 4 9 6 5 2
2 8 9 4 5 7 1 3 6
1 6 5 2 8 3 4 9 7
4 3 7 6 9 1 2 8 5
7 9 6 5 2 4 3 1 8
3 1 8 9 7 6 5 2 4
5 4 2 1 3 8 7 6 9
// E.

 ancora essere leggibile...
C'era un baco!
Ecco il codice corretto:
#include <stdio.h>
int s[81], m[82], k, i;
main() {
   for (i=0;i<81;++i) {
     scanf("%d",&s[i]);
     m[i]=s[i];
   }
   for(;;) {
     while (m[k]) k++;
     if (k>80) {
       for (i=0;i<81;++i) {
         printf("%d ",s[i]);
         if (i%9>7) printf("\n");
       }
       return;
     }
     if (++s[k]>9) {
       s[k--]=0;
       for(;m[k];)
         if (k--==0) return;
     } else {
       for (i=0;i<81;++i) {
         if (i==k || s[i]==0) continue;
         if (i%9==k%9 || i/9==k/9 ||
             (i/3)%3==(k/3)%3 && i/3/9==k/3/9)
           if (s[i]==s[k]) break;
       }
       if (i>80)
         k++;
     }
   }
}
E una versione "illeggibile":
#include<stdio.h>
int s[81],m[82],k,i;main(){for(i=
0;i<81;++i){scanf("%d",s+i);m[i]=
s[i];}l:i=0;while(m[k])k++;if(k>80
){for(;i<81;++i){printf("%d ",s[i]
);if(i%9>7)printf("\n");}return;}
if(++s[k]>9){s[k--]=0;for(;m[k];)
if(!k--)return;}else{for(;i<81&&(i
==k||s[i]==0||s[i]-s[k]||i%9-k%9&&
i/9-k/9&&(i/3%3-k/3%3||i/3/9-k/3/9
));++i);if(i>80)k++;}goto l;}
E.


Carino.
Giusto due appunti:
- la variabile k non è inizializzata
- i return devono tornare un int, visto come hai dichiarato il main.
Per il resto mi è piaciuto molto, e mi sono permesso di ioccc-zarlo
(se mi si passa il termine), tanto per aggiungere un po' di colore,
perdere qualche ora e tenermi in forma con questo tipo di boiate :-)
Ovviamente è da vedere su un terminale 80x24, con un font monospaced
(altrimenti la spaziatura non ha molto senso).
#include <stdio.h>
#define          S(a) (a?--k:k--)
#define          U (i>80)
#define          D return 0;0;
#define          O(q) i/q-k/q
#define          K(a,i) a[i]
#define E while(!U
#define     C printf(
#define     H scanf(
#define     I (??<
#define     N ??>)
#define     G =0
main() { int K(s,81),K(m,82),k,i; k=i G; E){ H"%d",
&K(s,i))            ;              K(m,i++)=K(s,i);
} l: i=0            ;              while(K(m,k++));
(S(1)>80            )              &&I E ){ C"%d ",
K(s,i) )            ;              (i++%9>7)&&I C"\
\n"); N;/*________*/}/*__________*/D N; (++K(s,k)>9
)? I K(s            ,              S(0)) G;  while(
K(m,k))             !              S(0)&&I D N; N:I
E&&( i==            k              ||!K(s,i)||K(s,i
)- K(s,k            )              ||i%9-k%9&& O(9)
&&(O(3%3)||O(3/9)))) ++i; U&&I k++; N; N; goto l; }
Bye!

 (altrimenti la spaziatura non ha molto senso).
Avevo pensato di usare qualche define, ma in definitiva mi pare che non 
si riesce a risparmiare caratteri. Sono riuscito a diminuire ancora di 
qualche carattere la versione "compatta" 
http://web.math.unifi.it/users/paolini/src/sudoku/
La cosa incredibile č che, come in tutti i programmi, anche in questo 
caso gran parte del codice serve per leggere l'input e scrivere 
l'output! L'algoritmo č veramente minimo...
E.