Solve triangle solitaire puzzle: Difference between revisions

Content added Content deleted
Line 1,958: Line 1,958:
o . . . o o o o o o o o o o o o o o o o o o o o
o . . . o o o o o o o o o o o o o o o o o o o o
</pre>
</pre>

=={{header|Picat}}==
This version use the constraint solver (cp).
<lang Picat>import cp.

go =>
% Solve the puzzle
puzzle(1,N,NumMoves,X,Y),
println("Show the moves (Move from .. over .. to .. ):"),
foreach({From,Over,To} in X)
println([from=From,over=Over,to=To])
end,
nl,
println("Show the list at each move (0 is an empty hole):"),
foreach(Row in Y)
foreach(J in 1..15)
printf("%2d ", Row[J])
end,
nl
end,
nl,

println("And an verbose version:"),
foreach(Move in 1..NumMoves)
if Move > 1 then
printf("Move from %d over %d to %d\n",X[Move-1,1],X[Move-1,2],X[Move-1,3])
end,
nl,
print_board([Y[Move,J] : J in 1..N]),
nl
end,
nl,
% fail, % uncomment to see all solutions
nl.

puzzle(Empty,N,NumMoves,X,Y) =>
N = 15,

% Peg 1 can move over 2 and end at 4, etc
% (for table_in/2)
moves(Moves),
ValidMoves = [],
foreach(From in 1..N)
foreach([Over,To] in Moves[From])
ValidMoves := ValidMoves ++ [{From,Over,To}]
end
end,

NumMoves = N-1,

% which move to make
X = new_array(NumMoves-1,3),
X :: 1..N,

% The board at move Move
Y = new_array(NumMoves,N),
Y :: 0..N,

% Initialize for row
Y[1,Empty] #= 0,
foreach(J in 1..N)
if J != Empty then
Y[1,J] #= J
end
end,

% make the moves
foreach(Move in 2..NumMoves)
sum([Y[Move,J] #=0 : J in 1..N]) #= Move,
table_in({From,Over,To}, ValidMoves),

% Get this move and update the rows
element(To,Y[Move-1],0),
element(From,Y[Move-1],FromVal), FromVal #!= 0,
element(Over,Y[Move-1],OverVal), OverVal #!= 0,

element(From,Y[Move],0),
element(To,Y[Move],To),
element(Over,Y[Move],0),

foreach(J in 1..N)
(J #!= From #/\ J #!= Over #/\ J #!= To) #=>
Y[Move,J] #= Y[Move-1,J]
end,
X[Move-1,1] #= From,
X[Move-1,2] #= Over,
X[Move-1,3] #= To
end,

Vars = Y.vars() ++ X.vars(),
solve($[split],Vars).

%
% The valid moves:
% Peg 1 can move over 2 and end at 4, etc.
%
moves(Moves) =>
Moves = [
[[2,4],[3,6]], % 1
[[4,7],[5,9]], % 2
[[5,8],[6,10]], % 3
[[2,1],[5,6],[7,11],[8,13]], % 4
[[8,12],[9,14]], % 5
[[3,1],[5,4],[9,13],[10,15]], % 6
[[4,2],[8,9]], % 7
[[5,3],[9,10]], % 8
[[5,2],[8,7]], % 9
[[6,3],[9,8]], % 10
[[7,4],[12,13]], % 11
[[8,5],[13,14]], % 12
[[8,4],[9,6],[12,11],[14,15]], % 13
[[9,5],[13,12]], % 14
[[10,6],[14,13]] % 15
].

%
% Print the board:
%
% 1
% 2 3
% 4 5 6
% 7 8 9 10
% 11 12 13 14 15
%
print_board(B) =>
printf(" %2d\n", B[1]),
printf(" %2d %2d\n", B[2],B[3]),
printf(" %2d %2d %2d\n", B[4],B[5],B[6]),
printf(" %2d %2d %2d %2d\n",B[7],B[8],B[9],B[10]),
printf(" %2d %2d %2d %2d %2d\n",B[11],B[12],B[13],B[14],B[15]),
nl.</lang>

Output
<pre>Show the moves (Move from .. over .. to .. ):
[from = 4,over = 2,to = 1]
[from = 6,over = 5,to = 4]
[from = 1,over = 3,to = 6]
[from = 12,over = 8,to = 5]
[from = 14,over = 13,to = 12]
[from = 6,over = 9,to = 13]
[from = 12,over = 13,to = 14]
[from = 15,over = 10,to = 6]
[from = 7,over = 4,to = 2]
[from = 2,over = 5,to = 9]
[from = 6,over = 9,to = 13]
[from = 14,over = 13,to = 12]
[from = 11,over = 12,to = 13]

Show the list at each move (0 is an empty hole):
0 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 0 3 0 5 6 7 8 9 10 11 12 13 14 15
1 0 3 4 0 0 7 8 9 10 11 12 13 14 15
0 0 0 4 0 6 7 8 9 10 11 12 13 14 15
0 0 0 4 5 6 7 0 9 10 11 0 13 14 15
0 0 0 4 5 6 7 0 9 10 11 12 0 0 15
0 0 0 4 5 0 7 0 0 10 11 12 13 0 15
0 0 0 4 5 0 7 0 0 10 11 0 0 14 15
0 0 0 4 5 6 7 0 0 0 11 0 0 14 0
0 2 0 0 5 6 0 0 0 0 11 0 0 14 0
0 0 0 0 0 6 0 0 9 0 11 0 0 14 0
0 0 0 0 0 0 0 0 0 0 11 0 13 14 0
0 0 0 0 0 0 0 0 0 0 11 12 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 13 0 0

And an verbose version:

0
2 3
4 5 6
7 8 9 10
11 12 13 14 15


Move from 4 over 2 to 1

1
0 3
0 5 6
7 8 9 10
11 12 13 14 15


Move from 6 over 5 to 4

1
0 3
4 0 0
7 8 9 10
11 12 13 14 15


Move from 1 over 3 to 6

0
0 0
4 0 6
7 8 9 10
11 12 13 14 15


Move from 12 over 8 to 5

0
0 0
4 5 6
7 0 9 10
11 0 13 14 15


Move from 14 over 13 to 12

0
0 0
4 5 6
7 0 9 10
11 12 0 0 15


Move from 6 over 9 to 13

0
0 0
4 5 0
7 0 0 10
11 12 13 0 15


Move from 12 over 13 to 14

0
0 0
4 5 0
7 0 0 10
11 0 0 14 15


Move from 15 over 10 to 6

0
0 0
4 5 6
7 0 0 0
11 0 0 14 0


Move from 7 over 4 to 2

0
2 0
0 5 6
0 0 0 0
11 0 0 14 0


Move from 2 over 5 to 9

0
0 0
0 0 6
0 0 9 0
11 0 0 14 0


Move from 6 over 9 to 13

0
0 0
0 0 0
0 0 0 0
11 0 13 14 0


Move from 14 over 13 to 12

0
0 0
0 0 0
0 0 0 0
11 12 0 0 0


Move from 11 over 12 to 13

0
0 0
0 0 0
0 0 0 0
0 0 13 0 0</pre>


=={{header|Prolog}}==
=={{header|Prolog}}==