Mercurial > repos > other > SevenLanguagesInSevenWeeks
view 3-Prolog/day3-8queens.pl @ 72:e05701354b6e
Add notes from Day 2
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 02 Feb 2018 20:59:06 +0000 |
parents | 69eb40c46798 |
children |
line wrap: on
line source
% Eight Queens problem, written from just the rules and a few hints on available approaches % which includes the "member/2" and other useful functions. % This will be MUCH more succinct than defining the entire board and trying % to operate on that! Half of the problem is approaching the problem correctly. eight_queens(List) :- % Check we've got the right length length(List, 8), % Check our values are all valid positions valid_board(List), % Pull out the rows rows(List, Rows), % Pull out the columns columns(List, Cols), % Pull out the diagonals (North-East/South-West) diagonals_sw_ne(List, Diags1), % Pull out the diagonals (North-West/South-East) diagonals_nw_se(List, Diags2), % Make sure we have no duplicates - based on the simple Sudoku solver fd_all_different(Rows), fd_all_different(Cols), fd_all_different(Diags1), fd_all_different(Diags2). valid_board([]). valid_board([Head|Tail]) :- valid_queen(Head), valid_board(Tail). % Queen location defined as a tuple valid_queen((Row, Col)) :- Range = [1,2,3,4,5,6,7,8], member(Row, Range), member(Col, Range). rows([], []). % This is a bit weird - Tail on the left matches and populates Tail on the right % Then we invoke the sub-goal and generate RowTail recursively, which populates % RowTail on the left. Easier than assignment, and probably tail recursive. rows([(Row, _)|Tail], [Row|RowTail]) :- rows(Tail, RowTail). columns([], []). columns([(_, Col)|Tail], [Col|ColTail]) :- columns(Tail, ColTail). diagonals_nw_se([], []). % Diagonals intersec the axis at consistent places, which we can approximate with Row + Col diagonals_nw_se([(Row,Col)|Tail], [Diag|DiagTail]) :- Diag is Row + Col, diagonals_nw_se(Tail, DiagTail). diagonals_sw_ne([], []). % Ditto the other diagonal, but use Row - Col because they slope the other way diagonals_sw_ne([(Row,Col)|Tail], [Diag|DiagTail]) :- Diag is Row - Col, diagonals_sw_ne(Tail, DiagTail).