/* Magic squares variant in Picat. % Solving a puzzle similar on ground of magic square % https://stackoverflow.com/questions/44153425/solving-a-puzzle-similar-on-ground-of-magic-square % """ % I am trying to solve a magic number and did the same but came on another problem of completing % the quadrilateral depending on the user defined conditions Example % % [ % | 47 % 8 7 _ 8 5 _ _ 5 | 40 % _ _ 5 9 _ _ 9 6 | 41 % _ 8 1 4 5 7 7 _ | 41 % 3 4 0 _ _ 3 0 _ | 15 % _ _ 3 9 6 _ 8 _ | 50 % 8 _ 6 _ 9 9 _ 3 | 54 % 2 9 _ _ 4 9 7 _ | 41 % 0 7 _ 1 _ 0 2 _ | 22 % -------------------- % 41 55 24 37 32 41 42 32 | 42 % ] % % % % Rules for the puzzle are same as that of magic square but repetition is allowed and the addition % on row and col and diagonal are mentioned at their end. Every blank can have value only between 0 and 9. % Any lead is appriciated for the program, input is a text file where x is blank, C++ preferred. % """ Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import cp. main => go. % % Before solve (a..b: domain of integers a..b) % 8 7 0..7 8 5 0..7 0..5 5 % 2..9 2..9 5 9 0..1 0..8 9 6 % 2..9 8 1 4 5 7 7 0..7 % 3 4 0 0..3 2 3 0 0..3 % 2..9 2..9 3 9 6 0..9 8 0..9 % 8 4..9 6 1..6 9 9 4..9 3 % 2 9 0..7 0..5 4 9 7 0..9 % 0 7 2..9 1 0..1 0 2 2..9 % % % One solution: % 8 7 0 8 5 7 0 5 % 2 7 5 9 0 3 9 6 % 9 8 1 4 5 7 7 0 % 3 4 0 0 2 3 0 3 % 9 9 3 9 6 3 8 3 % 8 4 6 6 9 9 9 3 % 2 9 2 0 4 9 7 8 % 0 7 7 1 1 0 2 4 % go => problem(1,M,RowSums,ColSums,Diag1,Diag2), magic_variant(M,RowSums,ColSums,Diag1,Diag2), print_square(M), nl. % num_solutions = 24813 go2 => problem(1,M,RowSums,ColSums,Diag1,Diag2), % All=findall(M,(magic_variant(M,RowSums,ColSums,Diag1,Diag2))), All=findall(M,(magic_variant(M,RowSums,ColSums,Diag1,Diag2),print_square(M))), println(num_solutions=All.len), nl. magic_variant(M,RowSums,ColSums,Diag1,Diag2) => N = M.len, M.vars() :: 0..9, foreach(I in 1..N) RowSums[I] #= sum([T : J in 1..N, T = M[I,J]]), ColSums[I] #= sum([T : J in 1..N, T = M[J,I]]) end, % diagonal sums Diag1 #= sum([M[I,I] : I in 1..N]), Diag2 #= sum([M[I,N-I+1] : I in 1..N]), print_square(M), solve([ff,split],M). print_square(Square) => N = Square.length, Pot1 = 1, Pot2 = 1, foreach(I in 1..N) foreach(J in 1..N) % writef("%3w ", Square[I,J]) Pot1 := Pot1 * fd_dom(Square[I,J]).len, fd_min_max(Square[I,J],Min,Max), Pot2 := Pot2 * (Max-Min+1), if Min < Max then printf("%d..%d ", Min,Max) else printf("%4w ", Min) end end, writef("\n") end, if Pot1 > 1 then println(pot1=Pot1) end, if Pot2 > 1 then println(pot2=Pot2) end, writef("\n"). problem(1,M,RowSums,ColSums,Diag1,Diag2) => M = [ [8,7,_,8,5,_,_,5], [_,_,5,9,_,_,9,6], [_,8,1,4,5,7,7,_], [3,4,0,_,_,3,0,_], [_,_,3,9,6,_,8,_], [8,_,6,_,9,9,_,3], [2,9,_,_,4,9,7,_], [0,7,_,1,_,0,2,_] ], Diag1 = 42, Diag2 = 47, RowSums = [40,41,41,15,50,54,41,22], ColSums = [41,55,24,37,32,41,42,32].