Jump to content

Knight's tour: Difference between revisions

Added a back tracking tie breaker
(Code crunch)
(Added a back tracking tie breaker)
Line 3,542:
 
=={{header|zkl}}==
Uses<lang zkl> // Use Warnsdorff's rule to findperform a solutionknights intour linearof a 8x8 board in time.
// linear time.
<lang zkl>class Board{
// See Pohl, Ira (July 1967),
// "A method for finding Hamilton paths and Knight's tours"
// http://portal.acm.org/citation.cfm?id=363463
// Uses back tracking as a tie breaker (for the few cases in a 8x8 tour)
<lang zkl>class Board{
ds:var[const]deltas=[[(dx,dy); T(-2,2); T(-1,1),isMoveOK.fp(x,y); _]].extend(
[[(dx,dy); T(-1,1); T(-2,2); _]]);
fcn init{
var [const] board=L();
(0).pump(64,board.append.fpM("1-",Void)); // fill board with Void
}
fcn idx(x,y){x*8+y}
fcn isMoveOK(x,y,dx,dy){x+ (0<=dx;x<8) and (0<=y+<8) and Void =dy;= board[idx(x,y)] }
(0<=x<8) and (0<=y<8) and Void == board[idx(x,y)]
}
fcn gyrate(x,y,f){ // walk all legal moves from (a,b)
dsdeltas.pump(List,'wrap([(dx,dy)]){f(x+dx,y+dy)});
ds:=[[(dx,dy); T(-2,2); T(-1,1),isMoveOK.fp(x,y); _]].extend(
[[(x+=dx,; y+=dy); Tif(-1isMoveOK(x,1y)); T(-2,2),isMoveOK.fpf(x,y); _]]else Void.Skip});
ds.pump(List,'wrap([(dx,dy)]){f(x+dx,y+dy)});
}
fcn count(x,y){ n:=Ref(0); gyrate(x,y,n.inc); n.value }
fcn moves(x,y){ gyrate(x,y,fcn(x,y){ T(x,y,count(x,y)) }) }
fcn knightsTour(x=0,y=0,n=1){ // using Warnsdorff's rule
n:board[idx(x,y)]=1n;
do{ while(m:=moves(x,y).reduce(fcn([(_,_,pc)]p,[(_,_,c)]n){
min:=m.reduce('wrap(pc,[(_,_,c)]){(pc<c) and ppc or nc},T(9,9,9));
m=m.filter('wrap([(_,_,c)]){c==min}); // moves with same min moves
board[idx(x,y)] = n;
if(m.len()>1){ // tie breaker time, may need to backtrack
x,y = m; n+=1;
} whilebs:=board.copy(x!=9);
if (64 == m.pump(Void,'wrap([(a,b)]){
board
board[idx(xa,yb)] = n;
n2:=knightsTour(a,b,n+1);
if (n2==64) return(Void.Stop,n2); // found a solution
board=bs.copy();
})) return(64);
return(0);
board }
else{
x,y = m[0]; n+=1;
board[idx(x,y)]=n;
}
} //while
return(n);
}
fcn toString{ board.pump(String,T.fp(Void.Read,7),
fcn(ns){vm.arglist.apply("%2d2s".fmt).concat(",")+"\n"});
}
}</lang>
Line 3,577 ⟶ 3,594:
{{out}}
<pre>
23 3,2034,17 5,3854,5519,6436,1529,4050
18 6,3721,22 2,6135,1656,3949,5418,6337
2133,24 4,1955,5620,5953,6230,4151,1428
3622,31 7,6032, 1,5048,4357,5838,5317
2511, 244,4923,3262,5731,52,1327,4258
30 8,3563,2810,5145,4460,47,1016, 739
343,2612,3361,4824, 541, 814,4559,1226
34,2964, 49,2742,13,46,1125, 640, 915
</pre>
Check that a solution for all squares is found:
 
<lang zkl>[[(x,y); [0..7]; [0..7];
{b:=Board(); n:=b.knightsTour(x,y); if(n!=64) b.println(">>>",x,",",y)} ]];</lang>
{{out}}Nada
 
{{omit from|GUISS}}
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.