flite-0.1: examples/Sudoku.hs
{
del x Nil = Nil;
del x (Cons y ys) =
case (==) x y of { True -> ys ; False -> Cons y (del x ys) };
diff xs Nil = xs;
diff xs (Cons y ys) = diff (del y xs) ys;
head (Cons x xs) = x;
tail (Cons x xs) = xs;
length Nil = 0;
length (Cons x xs) = (+) 1 (length xs);
sum Nil = 0;
sum (Cons x xs) = (+) x (sum xs);
null Nil = True;
null (Cons x xs) = False;
single Nil = False;
single (Cons x xs) = null xs;
minimum (Cons x xs) = min x xs;
min m Nil = m;
min m (Cons x xs) = case (<=) x m of { True -> min x xs ; False -> min m xs };
break p Nil = Pair Nil Nil;
break p (Cons x xs) =
case p x of {
True -> Pair Nil (Cons x xs);
False -> case break p xs of { Pair ys zs -> Pair (Cons x ys) zs };
};
filter p Nil = Nil;
filter p (Cons x xs) =
case p x of {
True -> Cons x (filter p xs);
False -> filter p xs;
};
zipWith f Nil ys = Nil;
zipWith f (Cons x xs) Nil = Nil;
zipWith f (Cons x xs) (Cons y ys) = Cons (f x y) (zipWith f xs ys);
notElem x Nil = True;
notElem x (Cons y ys) = and ((/=) x y) (notElem x ys);
and False x = False;
and True x = x;
not False = True;
not True = False;
or False x = x;
or True x = True;
any p Nil = False;
any p (Cons x xs) = or (p x) (any p xs);
all p Nil = True;
all p (Cons x xs) = and (p x) (all p xs);
map f Nil = Nil;
map f (Cons x xs) = Cons (f x) (map f xs);
append Nil ys = ys;
append (Cons x xs) ys = Cons x (append xs ys);
concat Nil = Nil;
concat (Cons xs xss) = append xs (concat xss);
concatMap f Nil = Nil;
concatMap f (Cons x xs) = append (f x) (concatMap f xs);
take n Nil = Nil;
take n (Cons x xs) =
case (==) n 0 of {
True -> Nil;
False -> Cons x (take ((-) n 1) xs);
};
drop n Nil = Nil;
drop n (Cons x xs) =
case (==) n 0 of {
True -> Cons x xs;
False -> drop ((-) n 1) xs;
};
groupBy n xs =
case null xs of {
True -> Nil;
False -> Cons (take n xs) (groupBy n (drop n xs));
};
id x = x;
comp f g x = f (g x);
boardsize = 9;
boxsize = 3;
cellvals = Cons 1 (Cons 2 (Cons 3 (
Cons 4 (Cons 5 (Cons 6 (
Cons 7 (Cons 8 (Cons 9 Nil))))))));
blank x = (==) x 0;
nodups Nil = True;
nodups (Cons x xs) = and (notElem x xs) (nodups xs);
singleton x = Cons x Nil;
cols (Cons xs Nil) = map singleton xs;
cols (Cons xs (Cons ys yss)) = zipWith Cons xs (cols (Cons ys yss));
boxs m = map concat (concatMap cols (groupBy 3 (map (groupBy 3) m)));
choices b = map (map choose) b;
choose e = case blank e of { True -> cellvals ; False -> Cons e Nil };
fixed css = concat (filter single css);
reduce css = map (remove (fixed css)) css;
remove fs cs = case single cs of { True -> cs ; False -> diff cs fs };
prune m = pruneBy boxs (pruneBy cols (pruneBy id m));
pruneBy f m = f (map reduce (f m));
blocked cm = or (void cm) (not (safe cm));
void m = any (any null) m;
safe cm = and (all (comp nodups fixed) cm)
(and (all (comp nodups fixed) (cols cm))
(all (comp nodups fixed) (boxs cm)));
best n cs = (==) (length cs) n;
expand cm =
let { n = minchoice cm } in
case break (any (best n)) cm of {
Pair rows1 rows2 ->
case break (best n) (head rows2) of {
Pair row1 row2 -> map (exp row1 row2 rows1 rows2) (head row2);
};
};
exp row1 row2 rows1 rows2 c =
append rows1 (append (Cons (append row1 (Cons (Cons c Nil)
(tail row2))) Nil)
(tail rows2));
minchoice m = minimum (filter gte2 (concatMap (map length) m));
gte2 x = (<=) 2 x;
search cm =
case blocked cm of {
True -> Nil;
False -> case all (all single) cm of {
True -> Cons cm Nil;
False -> concatMap (comp search prune) (expand cm);
};
};
sudoku b = map (map (map head)) (search (prune (choices b)));
emitRow Nil k = emit '\n' k;
emitRow (Cons x xs) k = emitInt x (emit ' ' (emitRow xs k));
emitMatrix Nil k = k;
emitMatrix (Cons x xs) k = emitRow x (emitMatrix xs k);
main = emitMatrix (head (
sudoku (Cons (Cons 0 (Cons 0 (Cons 0
(Cons 0 (Cons 0 (Cons 3
(Cons 0 (Cons 6 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 0 (Cons 0
(Cons 0 (Cons 0 (Cons 0
(Cons 0 (Cons 1 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 9 (Cons 7
(Cons 5 (Cons 0 (Cons 0
(Cons 0 (Cons 8 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 0 (Cons 0
(Cons 0 (Cons 9 (Cons 0
(Cons 2 (Cons 0 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 0 (Cons 8
(Cons 0 (Cons 7 (Cons 0
(Cons 4 (Cons 0 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 0 (Cons 3
(Cons 0 (Cons 6 (Cons 0
(Cons 0 (Cons 0 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 1 (Cons 0
(Cons 0 (Cons 0 (Cons 2
(Cons 8 (Cons 9 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 4 (Cons 0
(Cons 0 (Cons 0 (Cons 0
(Cons 0 (Cons 0 (Cons 0 Nil)))))))))
(Cons (Cons 0 (Cons 5 (Cons 0
(Cons 1 (Cons 0 (Cons 0
(Cons 0 (Cons 0 (Cons 0 Nil)))))))))
Nil))))))))))) 0;
}