comp30002-project-1/main.pl
2025-08-26 21:34:56 +10:00

74 lines
1.3 KiB
Prolog

% Three = [[0,14,10,35],[14,_,_,_],[15,_,_,_],[28,_,1,_]], puzzle_solution(Three)
% Three = [[0, 14, 10, 35], [14, 7, 2, 1], [15, 3, 7, 5], [28, 4, 1, 7]].
:- use_module(library(clpfd)).
%% puzzle_solution(+Puzzle)
%
puzzle_solution(Puzzle) :-
Puzzle = [_|Rows],
unify_diagonal(Puzzle),
maplist(valid_row, Rows),
transpose(Puzzle, TransposedPuzzle),
TransposedPuzzle = [_|Columns],
maplist(valid_row, Columns).
%% valid(+Row)
%
valid_row([Head|Row]) :-
Row ins 1..9,
all_distinct(Row),
valid_head(Head, Row),
label(Row).
%% valid_head(+Head, +Tail)
%
valid_head(Head, List) :-
sum(List, #=, Head)
; product(List, Head).
%% product(+List, -Product)
%
product(List, Product) :-
foldl(times, List, 1, Product).
%% times(?Int1, ?Int2, ?Int3)
%
% true if Int3 #= Int1 * Int2
times(Int1, Int2, Int3) :-
Int3 #= Int1 * Int2.
%% unify_diagonal(+Puzzle)
%
unify_diagonal(Puzzle) :-
main_diagonal(Puzzle, [_|Diag]),
all_same(Diag).
%% main_diagonal(+Matrix, -Diag)
%
main_diagonal(Matrix, Diag) :-
main_diagonal(Matrix, 0, Diag).
main_diagonal([], _, []).
main_diagonal([M|Ms], I, [D|Ds]) :-
nth0(I, M, D),
I1 is I + 1,
main_diagonal(Ms, I1, Ds).
%% all_same(+List)
%
all_same([Head|Tail]) :-
all_same(Head, Tail).
all_same(X, [X]).
all_same(Head, [X|Xs]) :-
Head #= X,
all_same(Head, Xs).