Download
:- use_module(library(clpfd)).
% A magic sequence of length N is a sequence [X0, X1, ..., X(N-1)] where
% Xi equals the number of times i appears in the sequence.
% Example (N=10): [6,2,1,0,0,0,1,0,0,0]
% define N and optionally pre-fill known values (use _ for unknowns)
puzzle(10, [6, 2, 1, 0, 0, 0, _, _, _, _]).
% solve the predefined puzzle
% solve(-Seq)
solve(Seq) :-
puzzle(N, Seq),
N1 is N - 1,
Seq ins 0..N1,
numlist(0, N1, Indices),
build_pairs(Indices, Seq, Pairs),
global_cardinality(Seq, Pairs),
label(Seq).
% general solver: find a magic sequence of length N from scratch
% magic_sequence(+N, -Seq)
magic_sequence(N, Seq) :-
length(Seq, N),
N1 is N - 1,
Seq ins 0..N1,
numlist(0, N1, Indices),
build_pairs(Indices, Seq, Pairs),
global_cardinality(Seq, Pairs),
label(Seq).
% zips indices and sequence variables into key-value pairs:
% build_pairs([0,1,2], [X0,X1,X2], [0-X0, 1-X1, 2-X2])
% build_pairs(+Indices, +Seq, -Pairs)
build_pairs([], [], []).
build_pairs([I|Is], [X|Xs], [I-X|Ps]) :-
build_pairs(Is, Xs, Ps).