/* Latin squares with diagonals in Picat. Inspired by Eric Taucher's post "Latin squares" in the SWI-Prolog forum https://swi-prolog.discourse.group/t/latin-squares/5056 http://en.wikipedia.org/wiki/Latin_square: """ A Latin square is an n X n table filled with n different symbols in such a way that each symbol occurs exactly once in each row and exactly once in each column. """ This variant also includes the constraints that the two diagonals must be distinct. Number of solutions (C: ffc/split): faster N #sols time ----------------------------- 1 1 0.0s 2 0 0.0s 3 0 0.0s 4 48 0.0s 5 960 0.003s 6 92160 0.528s 7 862848000 3124.13s (52min4.13s) Number of solutions (CP: ff) slower N #sols time ----------------------------- 1 1 0.001s 2 0 0.001s 3 0 0.001s 4 48 0.001s 5 960 0.005s 6 92160 1.428s 7 862848000 3624.9s (1hour24.9s) Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import cp. main => go. % % Print all solutions for N=4 % go ?=> N = 4, latin_square_diagonals(N, X), solve($[ffc],X), pretty_print(X), nl, fail, nl. go => true. % % A larger problem (first solution) % go2 ?=> N = 50, latin_square_diagonals(N, X), writeln(solve), solve([ffc],X), pretty_print(X), nl. go2 => true. % % Number of solutions for N=1..7 % go3 ?=> nolog, foreach(N in 1..7) time(Count = count_all((latin_square_diagonals(N,X),solve($[ffc,split],X)))), println(N=Count) end, nl. go3 => true. % % Solve the Latin squares with diagonals problem. % latin_square_diagonals(N, X) => X = new_array(N,N), X :: 1..N, foreach(Row in X) all_different(Row) end, foreach(Column in X.columns()) all_different(Column) end, all_different(diagonal1(X)), all_different(diagonal2(X)). pretty_print(X) => foreach(Row in X) writeln(Row) end.