annotate 3-Prolog/day3-8queens.pl @ 65:69eb40c46798

Add some "Eight Queens" solving Still trying to get my head in quite the right space.
author IBBoard <dev@ibboard.co.uk>
date Sun, 01 Oct 2017 19:59:48 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
65
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
1 % Eight Queens problem, written from just the rules and a few hints on available approaches
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
2 % which includes the "member/2" and other useful functions.
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
3 % This will be MUCH more succinct than defining the entire board and trying
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
4 % to operate on that! Half of the problem is approaching the problem correctly.
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
5
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
6 eight_queens(List) :-
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
7 % Check we've got the right length
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
8 length(List, 8),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
9 % Check our values are all valid positions
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
10 valid_board(List),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
11 % Pull out the rows
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
12 rows(List, Rows),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
13 % Pull out the columns
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
14 columns(List, Cols),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
15 % Pull out the diagonals (North-East/South-West)
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
16 diagonals_sw_ne(List, Diags1),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
17 % Pull out the diagonals (North-West/South-East)
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
18 diagonals_nw_se(List, Diags2),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
19
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
20 % Make sure we have no duplicates - based on the simple Sudoku solver
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
21 fd_all_different(Rows),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
22 fd_all_different(Cols),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
23 fd_all_different(Diags1),
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
24 fd_all_different(Diags2).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
25
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
26 valid_board([]).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
27 valid_board([Head|Tail]) :- valid_queen(Head), valid_board(Tail).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
28
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
29 % Queen location defined as a tuple
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
30 valid_queen((Row, Col)) :-
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
31 Range = [1,2,3,4,5,6,7,8],
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
32 member(Row, Range), member(Col, Range).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
33
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
34 rows([], []).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
35 % This is a bit weird - Tail on the left matches and populates Tail on the right
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
36 % Then we invoke the sub-goal and generate RowTail recursively, which populates
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
37 % RowTail on the left. Easier than assignment, and probably tail recursive.
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
38 rows([(Row, _)|Tail], [Row|RowTail]) :- rows(Tail, RowTail).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
39
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
40 columns([], []).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
41 columns([(_, Col)|Tail], [Col|ColTail]) :- columns(Tail, ColTail).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
42
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
43 diagonals_nw_se([], []).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
44 % Diagonals intersec the axis at consistent places, which we can approximate with Row + Col
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
45 diagonals_nw_se([(Row,Col)|Tail], [Diag|DiagTail]) :- Diag is Row + Col, diagonals_nw_se(Tail, DiagTail).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
46
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
47 diagonals_sw_ne([], []).
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
48 % Ditto the other diagonal, but use Row - Col because they slope the other way
69eb40c46798 Add some "Eight Queens" solving
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
49 diagonals_sw_ne([(Row,Col)|Tail], [Diag|DiagTail]) :- Diag is Row - Col, diagonals_sw_ne(Tail, DiagTail).