-
Notifications
You must be signed in to change notification settings - Fork 1
/
Answers.hs
54 lines (40 loc) · 1.11 KB
/
Answers.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
module Answers where
type Row a = [a]
type Matrix a = [Row a]
type Digit = Int
type Grid = Matrix Digit
boxSize = 2
gridSize = boxSize * boxSize
solve :: Grid -> [Grid]
solve = filter valid . completions
completions :: Grid -> [Grid]
completions = expand . choices
choices :: Grid -> Matrix [Digit]
choices = map (map choice)
where
choice 0 = [1..gridSize]
choice i = [i]
expand :: Matrix [Digit] -> [Grid]
expand = cp . map cp
cp :: [[a]] -> [[a]]
cp [] = [[]]
cp (xs:xss) = [x:ys | x <- xs, ys <- cp xss]
valid :: Grid -> Bool
valid grid = valid' rows && valid' cols && valid' boxs
where valid' f = all nodups (f grid)
nodups :: Eq a => [a] -> Bool
nodups [] = True
nodups (x:xs) = (not $ elem x xs) && nodups xs
rows :: Matrix a -> Matrix a
rows = id
cols :: Matrix a -> Matrix a
cols [xs] = [[x] | x <- xs]
cols (xs:xss) = zipWith (:) xs (cols xss)
boxs :: Matrix a -> Matrix a
boxs = map ungroup . ungroup . map cols . group . map group
group :: [a] -> [[a]]
group [] = []
group xs = hd:group tl
where (hd, tl) = splitAt boxSize xs
ungroup :: [[a]] -> [a]
ungroup = concat