-module(sudoku) .

-export([sudoku/1,
	 run/0]) .

zip ([],[]) -> [] ;
zip ([],[_]) -> [] ;
zip ([_],[]) -> [] ;
zip ([A|As],[[B|Bs]|Bss]) -> [[A,B|Bs]|zip(As,Bss)] ;
zip ([A|As],[B|Bs]) -> [[A,B]|zip(As,Bs)] .
transpose([[A|As]]) -> [A|As] ;
transpose([[A|As]|Ass]) -> zip([A|As],transpose(Ass)) .

unique([]) -> true ;
unique([A,B]) when A =/= B -> true ;
unique([A,B]) when A =:= B -> false ;
unique([A,B|_]) when A =:= B -> false ;
unique([A,B|Rest]) when A =/= B -> unique([A|Rest]) and unique([B|Rest]) .

block([]) -> [] ;
block([[],[],[]|Rest]) -> block(Rest) ;
block([[A0,B0,C0|Row0], [A1,B1,C1|Row1], [A2,B2,C2|Row2] | Rest]) -> 
	[[A0,B0,C0,A1,B1,C1,A2,B2,C2] | block([Row0,Row1,Row2|Rest]) ] .

domian(?) -> lists:seq(1,9) ;
domain(A) when is_number(A), A > 0, A < 10 -> [A] .

sudoku([]) -> [] ;
sudoku([A|As]) when is_atom(A), A =:= ? -> lists:seq(1,9) ;
sudoku([A|As]) when is_number(A), A > 0, A < 10 -> [[A]|sudoku(As)] ;
sudoku([[A|As]|Ass]) -> [sudoku([A|As]),sudoku(Ass)] .


print(What) -> io:format("~p~n",[What]),What .

run() ->
	print([zip]),
	A0 = [a,b,c],
	A1 = [d,e,f],
	AA = zip(A0,A1),
	print(AA),

	print([more,zip]),
	C = [a,b,c],
	Cs = [[e,h],[f,i],[g,j]],
	CC = zip(C,Cs),
	print(CC),

	print([matrix]),
	T = [[a,b,c],[d,e,f],[g,h,i]],
	print(T),

	print([transpose]),
	TT = transpose(T),
	print(TT),
	
	print([block]),
	B = [[a,b,c],[d,e,f],[g,h,i]],
	print(B),
	BB = block(B),
	print(BB),

	print([unique]),
	U = unique([1,2,3,4]),
	print([U]),
	D = unique([2,3,4,2]),
	print([D]),

	init:stop().
