between(I, J, K) :-
    I =< J,
    (   I = K
    ;   I1 is I+1,
        between(I1, J, K)
    ).

legal_queens(N, Row, []) :- N =:= Row - 1.
legal_queens(N, Row1, [(Row1, Col1)|Queens]) :-
    Row1 < N + 1,
    Row2 is Row1 + 1,
    legal_queens(N, Row2, Queens),
    between(1,N,Col1),
    no_attacks((Row1, Col1), Queens).

no_attacks(_, []).
no_attacks((Row1, Col1), [(Row2, Col2)|OtherQueens]) :-
    Row1 \= Row2,
    Col1 \= Col2,
    abs(Row1 - Row2) =\= abs(Col1 - Col2),
    no_attacks((Row1, Col1), OtherQueens).

n_queens(N, Solution) :-
    legal_queens(N, 1, Solution).

one_queens(N, Solution) :-
    legal_queens(N, 1, Solution), !.

printNQueen(N) :- n_queens(N, Solution), write(Solution), write('\n'), fail.
printNQueen(_).

printOneQueen(N) :- one_queens(N, Solution), write(Solution), write('\n'), fail.
printOneQueen(_).

timeNQueen(N) :- cputime(X), printNQueen(N), cputime(Y), T is Y-X, write(T).

timeOneQueen(N) :- cputime(X), printOneQueen(N), cputime(Y), T is Y-X, write(T).