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 a b = sumonad
  if a <= b then (return a | range (a+1) b)

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

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

(*
let rec parse_add = sumonad
  for v1 <- parse_times do
    for f <- parse_add_aux do
      return (f v1)
    done
  done
and parse_add_aux = sumonad
  begin
    | #look "+";
      for v2 <- parse_times do
	for f <- parse_add_aux do
	  return (fun v1 -> f (v1 + v2))
	done
      done
    | return (fun v1 -> v1)
  end
*)