Хотел вечерком размять мозг — набросать какой-нибудь особенно красивый решатель Sudoku на Ocaml. Но возникла мысль изучить вражеские аналоги. Итак, решатель Sudoku размером 800 с небольшим байт:
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 ()) ()
Вы посмотрите эту красоту, это же [почти] совершенство! А если учесть, что 272 байта — это чтение задачи с STDIN и вывод результата, размер кода сокращается до менее чем 600 байт.
Впрочем, Perl традиционно отличился своей минималистической магической мешаниной:
use integer;@A=split//,<>;sub R{for$i(0..80){next if$A[$i];my%t=map{$_/9 ==$i/9||$_%9==$i%9||$_/27==$i/27&&$_%9/3==$i%9/3?$A[$_]:0=>1}0..80;R($A[ $i]=$_)for grep{!$t{$_}}1..9;return$A[$i]=0}die@A}R
Ну и специалисты по PHP тоже выразились: http://www.weberdev.com/get_example-4243.html