1. Sébastien Ferré
  2. ocaml-lib

Source

ocaml-lib / sumonad / essai.ml


let rec safe_aux (p1,p2,p3) = (* low diagonal, line, high diagonal *)
  function
    | [] -> true
    | p::ps1 -> p <> p1 && p <> p2 && safe_aux (p1-1,p2,p3+1) ps1
let safe p ps1 = safe_aux (p-1,p,p+1) ps1

let state =
object (self)
  method print_line s = print_endline s; Sumonad.Stream.Single (Sumonad.Result (), self)
end

let rec range n = sumonad
  begin
    | return n
    | when n>1; range (n-1)
  end

let rec nqueens n k = sumonad
  begin
    if k=0
    then begin
      # print_line "k=0";
      return [] end
    else
      for ps1 <- nqueens n (k-1) do
	for p <- range n do
	  when (safe p ps1);
	  let ps = p::ps1 in
	  return ps
	done
      done
  end

let _ =
  let n = try int_of_string Sys.argv.(1) with _ -> 4 in
  let k = try int_of_string Sys.argv.(2) with _ -> 10 in
  let print ps = List.iter (fun p -> print_int p; print_char ' ') ps; print_newline () in
  Sumonad.kiter print k (nqueens n n) state