caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Marco Maggesi <maggesi@math.unice.fr>
To: caml-list@inria.fr
Subject: Yet another sudoku solver (838 bytes)
Date: Sat, 19 Nov 2005 12:41:32 +0000 (UTC)	[thread overview]
Message-ID: <dln6hs$eat$1@sea.gmane.org> (raw)

While we are there, this is my soduku solver.  It is not as efficient
as the other solver proposed in this list, but it takes a fraction of
seconds to compute a solution on a P4 anyway.

Perhaps, the distinguishing feature of this implementation is that it
uses higher order functions in an essential way (that is, the
accumulator argument of the "fold" in the body of "search" is a
function).  And it is only 838 of code of clear (?) and concise code.

BTW, now that we have so many sudoku solvers, wouldn't be be nice to
have one with a computer certified implementation?

Marco

------------------------------------------------------------

Instructions:

  $ ocamlopt -o sudoku sudoku.ml
  
  $ cat schema
  0 6 0 1 0 0 0 5 0
  0 0 8 3 0 5 6 0 0
  2 0 0 0 0 0 0 0 1
  8 0 0 4 0 7 0 0 6
  0 0 6 0 0 0 3 0 0
  7 0 0 9 0 1 0 0 4
  5 0 0 0 0 0 0 0 2
  0 0 7 0 0 6 9 0 0
  0 4 0 0 0 8 0 7 0

  $ ./sudoku < schema
  9 6 3 1 7 4 2 5 8
  1 7 8 3 2 5 6 4 9
  2 5 4 6 8 9 7 3 1
  8 2 1 4 3 7 5 9 6
  4 9 6 8 5 2 3 1 7
  7 3 5 9 6 1 8 2 4
  5 8 9 7 1 3 4 6 2
  3 1 7 2 4 6 9 8 5
  6 4 2 5 9 8 1 7 3



------------------- 8< ----------------------------------- 8<  -------
include Set.Make(struct type t = (int * int) * int let compare = compare end)
 
let (@) g f x = g (f x) and id x = x and sw f x y = f y x and zip x y = (x, y)
 
let fold9 f = let rec loop i = if i>8 then id else loop (i+1) @ f i in loop 0
 
let fold81 f = fold9 (fold9 @ (@) f @ zip)
 
let mark ((i,j),x as e) : t -> t =
  add e @ fold9 (fun k -> remove ((i/3*3 + k/3, j/3*3 + k mod 3), x) @
    remove ((i,j),k) @ remove ((i,k),x) @ remove ((k,j),x))
 
let search =
  let g p f s = fold (f @ sw mark s) (filter ((=) p @ fst) s) in
  fold81 g
 
let read () =
  let f p = Scanf.scanf "%d " (fun x -> if x>0 then mark (p,x-1) else
  id) in
  fold81 f (fold81 (fold9 @ ((@) add @ zip)) empty)
 
let print s () =
  let pr ((i,j),x) = Printf.printf "%d%c" (x+1) (if j=8 then '\n' else ' ') in
  iter pr s; print_newline ();;
 
search print (read ()) ();;


             reply	other threads:[~2005-11-19 12:43 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-19 12:41 Marco Maggesi [this message]
2005-11-19 15:09 ` Yet another OCaml Webserver?! (was: Re: [Caml-list] Yet another sudoku solver (838 bytes)) Oliver Bandel
2005-11-19 15:41   ` Thomas Fischbacher
2005-11-19 15:55   ` William Neumann
2005-11-19 16:05     ` Oliver Bandel
2005-11-19 16:29       ` William Neumann
2005-11-19 17:28   ` Jonathan Bryant
2005-11-19 20:09   ` Jonathan Roewen
2005-11-19 20:19     ` Oliver Bandel
2005-11-19 20:32       ` skaller
2005-11-19 20:50         ` Jonathan Roewen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='dln6hs$eat$1@sea.gmane.org' \
    --to=maggesi@math.unice.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).