1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 35a3110598 Squashed 'software/chuffed/' content from commit 2ed0c015
git-subtree-dir: software/chuffed
git-subtree-split: 2ed0c01558d2a5c49c1ce57e048d32c17adf92d3
2021-06-18 09:36:35 +10:00

72 lines
2.3 KiB
MiniZinc

include "globals.mzn";
include "flatzinc.mzn";
set of int: Piles = 1..17;
set of int: Layers = 1..3;
set of int: Cards = 1..52;
array[Piles, Layers] of int: layout; % layout of cards by pile and layer
array[Cards] of int: ctop; % get pile by card index
array[Cards] of int: ctol; % get layer by card index
ctop = [-1] ++ [i | c in Cards, i in Piles, j in Layers where layout[i,j] = c];
ctol = [-1] ++ [j | c in Cards, i in Piles, j in Layers where layout[i,j] = c];
array[1..416, 1..2] of int: neighbours; % next card is +/- 1 of current card
neighbours = array2d(1..416, 1..2,
[i+1 | n in 0..831, i in 0..51 where
(n mod 2 = 0 /\ i = n div 16) \/
(n mod 4 = 1 /\ i = (n div 16 + (n mod 16) div 4 * 13 + 51) mod 52) \/
(n mod 4 = 3 /\ i = (n div 16 + (n mod 16) div 4 * 13 + 1) mod 52)]);
array[Cards] of var Cards: x; % Position of card
array[Cards] of var Cards: y :: is_output; % Card at position
% Problem constraints
constraint y[1] == 1; % Ace of spades in first pos
constraint inverse(x,y);
constraint
forall(i in 1..17, j in 1..2) (x[layout[i,j]] < x[layout[i,j+1]]);
constraint forall(i in 1..51) (table([y[i], y[i+1]], neighbours));
% Symmetry breaking constraints
constraint forall (i in 1..13, s1 in 0..3, s2 in s1+1..3) (
let { int: n1 = s1*13+i, int: n2 = s2*13+i } in
if (n1 != 1 /\ ctop[n1] != ctop[n2]) then
let { int: o1 = if ctol[n2] < ctol[n1] then n2 else n1 endif,
int: o2 = if ctol[n2] < ctol[n1] then n1 else n2 endif } in
if ctol[o2] == 3 then
if ctol[o1] == 1 then
x[o1] < x[o2]
else
bool_clause([x[o2] < x[layout[ctop[o1],ctol[o1]-1]],
x[o1] < x[o2]], [])
endif
else
if ctol[o1] == 1 then
bool_clause([x[layout[ctop[o2],ctol[o2]+1]] < x[o1],
x[o1] < x[o2]], [])
else
bool_clause([x[layout[ctop[o2],ctol[o2]+1]] < x[o1],
x[o2] < x[layout[ctop[o1],ctol[o1]-1]],
x[o1] < x[o2]], [])
endif
endif
else true endif
);
% Branching heuristic
array [1..51] of var int: pref_order =
[x[i] | i in Cards where ctol[i] = 1] ++
[x[i] | i in Cards where ctol[i] = 2] ++
[x[i] | i in Cards where ctol[i] = 3];
solve :: int_search(pref_order, smallest, indomain_min, complete) satisfy;