fork(1) download
  1. :- initialization(main).
  2.  
  3.  
  4. solve(T) :-
  5. maplist(domain_1_9, T)
  6. , sudoku_rows(T)
  7. , transpose(T,Tmp), sudoku_rows(Tmp)
  8. , sudoku_blocks(T)
  9. , maplist(fd_labeling, T)
  10. .
  11.  
  12. domain_1_9(T) :- fd_domain(T,1,9).
  13. sudoku_rows(T) :- maplist(fd_all_different, T).
  14.  
  15. sudoku_blocks(T) :-
  16. findall(mn(M,N), (between(1,3,M), between(1,3,N)), MN)
  17. , maplist(block2D_different(T), MN)
  18. .
  19.  
  20. block2D_different(T, mn(M,N)) :-
  21. block3(M,T,T3), maplist(block3(N), T3, T9)
  22. , concat(T9,Xs), fd_all_different(Xs)
  23. . % where
  24. block3(M,Xs,Ys) :-
  25. append(Pre,Zs,Xs), length(Pre,L), L is (M - 1) * 3
  26. , prefix(Ys,Zs) , length(Ys,3)
  27. .
  28.  
  29.  
  30. % utils/list
  31. between(M,N,X) :- X = M ; M < N -> M1 is M + 1, between(M1,N,X).
  32.  
  33. maplist(_,[]).
  34. maplist(F,[X|Xs]) :- call(F,X), maplist(F,Xs).
  35.  
  36. maplist(_,[],[]).
  37. maplist(F,[X|Xs],[Y|Ys]) :- call(F,X,Y), maplist(F,Xs,Ys).
  38.  
  39. maplist(_,[],[],[]).
  40. maplist(F,[X|Xs],[Y|Ys],[Z|Zs]) :- call(F,X,Y,Z), maplist(F,Xs,Ys,Zs).
  41.  
  42. concat([],[]).
  43. concat([X|Xs],Ys) :- append(X,Zs,Ys), concat(Xs,Zs).
  44.  
  45. transpose([],[]).
  46. transpose([[X|Xh]|XX],[[X|Yh]|YY]) :-
  47. maplist(bind_head, Yh, XX, XY)
  48. , maplist(bind_head, Xh, YY, YX)
  49. , transpose(XY,YX)
  50. . % where
  51. bind_head([],[],[]).
  52. bind_head(X,[X|XY],XY).
  53.  
  54.  
  55. % tests
  56. test([ [_,_,3,_,_,_,_,_,_]
  57. , [4,_,_,_,8,_,_,3,6]
  58. , [_,_,8,_,_,_,1,_,_]
  59. , [_,4,_,_,6,_,_,7,3]
  60. , [_,_,_,9,_,_,_,_,_]
  61. , [_,_,_,_,_,2,_,_,5]
  62. , [_,_,4,_,7,_,_,6,8]
  63. , [6,_,_,_,_,_,_,_,_]
  64. , [7,_,_,6,_,_,5,_,_]
  65. ]).
  66.  
  67. main :- test(T), solve(T), maplist(show,T), halt.
  68. show(X) :- write(X), nl.
Success #stdin #stdout 0.03s 68352KB
stdin
Standard input is empty
stdout
[1,2,3,4,5,6,7,8,9]
[4,5,7,1,8,9,2,3,6]
[9,6,8,3,2,7,1,5,4]
[2,4,9,5,6,1,8,7,3]
[5,7,6,9,3,8,4,1,2]
[8,3,1,7,4,2,6,9,5]
[3,1,4,2,7,5,9,6,8]
[6,9,5,8,1,4,3,2,7]
[7,8,2,6,9,3,5,4,1]