- :- initialization(main). 
-   
-   
- solve(T) :- 
-     maplist(domain_1_9, T) 
-   , sudoku_rows(T) 
-   , transpose(T,Tmp), sudoku_rows(Tmp) 
-   , sudoku_blocks(T) 
-   , maplist(fd_labeling, T) 
-   . 
-   
- domain_1_9(T)  :- fd_domain(T,1,9). 
- sudoku_rows(T) :- maplist(fd_all_different, T). 
-   
- sudoku_blocks(T) :- 
-     findall(mn(M,N), (between(1,3,M), between(1,3,N)), MN) 
-   , maplist(block2D_different(T), MN) 
-   . 
-   
- block2D_different(T, mn(M,N)) :- 
-     block3(M,T,T3), maplist(block3(N), T3, T9) 
-   , concat(T9,Xs), fd_all_different(Xs) 
-   . % where 
-     block3(M,Xs,Ys) :- 
-         append (- Pre ,- Zs ,- Xs ), length(- Pre ,- L ),-  L is  (- M  - 1) * 3
-       ,-  prefix (- Ys ,- Zs )    , length(- Ys ,3)
 
-       . 
-   
-   
- % utils/list 
- between(M,N,X) :- X = M ; M < N -> M1 is M + 1, between(M1,N,X). 
-   
- maplist(_,[]). 
- maplist(F,[X|Xs]) :- call(F,X), maplist(F,Xs). 
-   
- maplist(_,[],[]). 
- maplist(F,[X|Xs],[Y|Ys]) :- call(F,X,Y), maplist(F,Xs,Ys). 
-   
- maplist(_,[],[],[]). 
- maplist(F,[X|Xs],[Y|Ys],[Z|Zs]) :- call(F,X,Y,Z), maplist(F,Xs,Ys,Zs). 
-   
- concat([],[]). 
- concat([X|Xs],Ys) :- append(X,Zs,Ys), concat(Xs,Zs). 
-   
- transpose([],[]). 
- transpose([[X|Xh]|XX],[[X|Yh]|YY]) :- 
-     maplist(bind_head, Yh, XX, XY) 
-   , maplist(bind_head, Xh, YY, YX) 
-   , transpose(XY,YX) 
-   . % where 
-     bind_head([],[],[]). 
-     bind_head(X,[X|XY],XY). 
-   
-   
- % tests 
- test([ [_,_,3,_,_,_,_,_,_] 
-      , [4,_,_,_,8,_,_,3,6] 
-      , [_,_,8,_,_,_,1,_,_] 
-      , [_,4,_,_,6,_,_,7,3] 
-      , [_,_,_,9,_,_,_,_,_] 
-      , [_,_,_,_,_,2,_,_,5] 
-      , [_,_,4,_,7,_,_,6,8] 
-      , [6,_,_,_,_,_,_,_,_] 
-      , [7,_,_,6,_,_,5,_,_] 
-      ]). 
-   
- main :- test(T), solve(T), maplist(show,T), halt. 
				Oi0gaW5pdGlhbGl6YXRpb24obWFpbikuCgoKc29sdmUoVCkgOi0KICAgIG1hcGxpc3QoZG9tYWluXzFfOSwgVCkKICAsIHN1ZG9rdV9yb3dzKFQpCiAgLCB0cmFuc3Bvc2UoVCxUbXApLCBzdWRva3Vfcm93cyhUbXApCiAgLCBzdWRva3VfYmxvY2tzKFQpCiAgLCBtYXBsaXN0KGZkX2xhYmVsaW5nLCBUKQogIC4KCmRvbWFpbl8xXzkoVCkgIDotIGZkX2RvbWFpbihULDEsOSkuCnN1ZG9rdV9yb3dzKFQpIDotIG1hcGxpc3QoZmRfYWxsX2RpZmZlcmVudCwgVCkuCgpzdWRva3VfYmxvY2tzKFQpIDotCiAgICBmaW5kYWxsKG1uKE0sTiksIChiZXR3ZWVuKDEsMyxNKSwgYmV0d2VlbigxLDMsTikpLCBNTikKICAsIG1hcGxpc3QoYmxvY2syRF9kaWZmZXJlbnQoVCksIE1OKQogIC4KCmJsb2NrMkRfZGlmZmVyZW50KFQsIG1uKE0sTikpIDotCiAgICBibG9jazMoTSxULFQzKSwgbWFwbGlzdChibG9jazMoTiksIFQzLCBUOSkKICAsIGNvbmNhdChUOSxYcyksIGZkX2FsbF9kaWZmZXJlbnQoWHMpCiAgLiAlIHdoZXJlCiAgICBibG9jazMoTSxYcyxZcykgOi0KICAgICAgICBhcHBlbmQoUHJlLFpzLFhzKSwgbGVuZ3RoKFByZSxMKSwgTCBpcyAoTSAtIDEpICogMwogICAgICAsIHByZWZpeChZcyxacykgICAgLCBsZW5ndGgoWXMsMykKICAgICAgLgoKCiUgdXRpbHMvbGlzdApiZXR3ZWVuKE0sTixYKSA6LSBYID0gTSA7IE0gPCBOIC0+IE0xIGlzIE0gKyAxLCBiZXR3ZWVuKE0xLE4sWCkuCgptYXBsaXN0KF8sW10pLgptYXBsaXN0KEYsW1h8WHNdKSA6LSBjYWxsKEYsWCksIG1hcGxpc3QoRixYcykuCgptYXBsaXN0KF8sW10sW10pLgptYXBsaXN0KEYsW1h8WHNdLFtZfFlzXSkgOi0gY2FsbChGLFgsWSksIG1hcGxpc3QoRixYcyxZcykuCgptYXBsaXN0KF8sW10sW10sW10pLgptYXBsaXN0KEYsW1h8WHNdLFtZfFlzXSxbWnxac10pIDotIGNhbGwoRixYLFksWiksIG1hcGxpc3QoRixYcyxZcyxacykuCgpjb25jYXQoW10sW10pLgpjb25jYXQoW1h8WHNdLFlzKSA6LSBhcHBlbmQoWCxacyxZcyksIGNvbmNhdChYcyxacykuCgp0cmFuc3Bvc2UoW10sW10pLgp0cmFuc3Bvc2UoW1tYfFhoXXxYWF0sW1tYfFloXXxZWV0pIDotCiAgICBtYXBsaXN0KGJpbmRfaGVhZCwgWWgsIFhYLCBYWSkKICAsIG1hcGxpc3QoYmluZF9oZWFkLCBYaCwgWVksIFlYKQogICwgdHJhbnNwb3NlKFhZLFlYKQogIC4gJSB3aGVyZQogICAgYmluZF9oZWFkKFtdLFtdLFtdKS4KICAgIGJpbmRfaGVhZChYLFtYfFhZXSxYWSkuCgoKJSB0ZXN0cwp0ZXN0KFsgW18sXywzLF8sXyxfLF8sXyxfXQogICAgICwgWzQsXyxfLF8sOCxfLF8sMyw2XQogICAgICwgW18sXyw4LF8sXyxfLDEsXyxfXQogICAgICwgW18sNCxfLF8sNixfLF8sNywzXQogICAgICwgW18sXyxfLDksXyxfLF8sXyxfXQogICAgICwgW18sXyxfLF8sXywyLF8sXyw1XQogICAgICwgW18sXyw0LF8sNyxfLF8sNiw4XQogICAgICwgWzYsXyxfLF8sXyxfLF8sXyxfXQogICAgICwgWzcsXyxfLDYsXyxfLDUsXyxfXQogICAgIF0pLgoKbWFpbiA6LSB0ZXN0KFQpLCBzb2x2ZShUKSwgbWFwbGlzdChzaG93LFQpLCBoYWx0LgpzaG93KFgpIDotIHdyaXRlKFgpLCBubC4=