let knightsmoves = [(-1,-2); (-2,-1); (1,-2); (-2,1); (-1,2); (2,-1); (1,2); (2,1)];; (* Uncomment the following if you want alternative order of the moves *) (* let knightsmoves = [(1, 2); (1, -2); (-1, 2); (-1, -2); (2, 1); (2, -1); (-2, 1); (-2, -1)];; *) let add (a,b) (c,d) = (a+c,b+d);; let onboard (a,b) = (a >= 0) && (a < 8) && (b >= 0) && (b < 8);; let moves pos = List.filter (onboard) (List.map (add pos) knightsmoves);; let filmoves pos soln = List.filter (fun b -> not (List.mem b soln)) (moves pos);; let compval soln pos1 pos2 = (List.length (filmoves pos1 soln)) - (List.length (filmoves pos2 soln));; let sortedmoves soln = List.sort (compval soln) (filmoves (List.hd soln) (List.tl soln));; let rec do_until f = function | [] -> [] | h::t -> match f h with | [] -> do_until f t | answer -> answer;; let rec extend1 start len soln = if (len == 64) then if List.mem start (moves (List.hd soln)) then soln else [] else do_until (fun b -> extend1 start (len+1) (b::soln)) (sortedmoves soln);; let extend start = extend1 start 1 [start];; let rec indexadd n pos soln = if (List.hd soln) = pos then n else indexadd (n-1) pos (List.tl soln);; let index pos soln = indexadd 64 pos soln;; let printsoln soln = (* Print the top line *) for i = 1 to 8 do Printf.printf "-----"; done; Printf.printf "-\n"; for i = 0 to 7 do for j = 0 to 7 do Printf.printf "| %2i " (index (i,j) soln); done; Printf.printf "|\n"; (* Print a line below *) for j = 1 to 8 do Printf.printf "-----"; done; Printf.printf "-\n"; done;; if (!Sys.interactive) then (* If we are loaded in the interpreter do nothing *) () else if (Array.length Sys.argv) > 2 then printsoln (extend (int_of_string Sys.argv.(1), int_of_string Sys.argv.(2)) ) else Printf.printf "Usage: %s x y\n" (Sys.argv.(0));;