%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% queens.pi
%%% by Neng-Fa Zhou
%%% http://people.cs.kuleuven.be/~bart.demoen/PrologProgrammingContests/2013/probs2013.pdf
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
import sat.
main => test.
test =>
evil_and_nice(8,Evil,Nice),
writeln($evil(Evil)),
writeln($nice(Nice)).
evil_and_nice(N,Evil,Nice) =>
QB = new_array(N,N), % Bad (evial) queens
QG = new_array(N,N), % Good (nice ) queens
QB :: 0..1,
QG :: 0..1,
NQB :: 1..N,
sum([QB[I,J] : I in 1..N, J in 1..N]) #= NQB,
sum([QG[I,J] : I in 1..N, J in 1..N]) #= NQG,
abs(NQG-NQB) #=< 1,
foreach(I in 1..N, J in 1..N, I1 in 1..N, J1 in 1..N)
if (I==I1 || J==J1 || I+J==I1+J1 || I-J == I1-J1) then
if (I,J) != (I1,J1) then QB[I,J] #=> #~ QB[I1,J1] end,
QB[I,J] #=> #~ QG[I1,J1]
end
end,
solve([$max(NQB+NQG)],(QB,QG)),
Evil = [$pos(I,J) : I in 1..N, J in 1..N, QB[I,J]==1],
Nice = [$pos(I,J) : I in 1..N, J in 1..N, QG[I,J]==1].