This solves Sudoku by using backtracking. Accepts one grid where 0 represents a missing number. Here are some examples: http://norvig.com/easy50.txt
The program is quite slow. Input is stdin.
import Data.Char (isDigit)
import Data.List (intersperse, delete)
printGrid [] = []
printGrid x = (intersperse ' ' $ take 9 x) ++ "\n" ++ (printGrid $ drop 9 x)
solve x = if isSolved x then x
else
firstSolved cands
where
firstSolved [] = []
firstSolved (c:cs) = if isSolved trial then trial else firstSolved cs
where
trial = solve c
cands = candidates x
isSolved x = (length x == 81) && (not $ elem '0' x) && (isValidCandidate x)
candidates x = filter isValidCandidate [(takeWhile (/='0') x) ++ z ++ (tail $ dropWhile (/='0') x) | z <- map show [1..9]]
isValidCandidate x = not $ any (isInvalidCand x) [0..80]
isInvalidCand x i = (x !! i /= '0') &&
any (elem ic) [row, col, unit]
where
ix = mod i 9
iy = quot i 9
ic = x !! i
row = [x !! a | a <- [9*iy..(9*iy + 8)], a /= i]
col = [x !! a | a <- [ix, (ix + 9)..(ix + 72)], a /= i]
icx = (quot ix 3) * 3
icy = (quot iy 3) * 3
si = (9*icy) + icx
unit = map (x !!) (delete i [si, si + 1, si + 2, si + 9, si + 10, si + 11, si + 18, si + 19, si + 20])
main :: IO ()
main = interact $ printGrid . solve . filter isDigit