Skip to content

Instantly share code, notes, and snippets.

@AndrasKovacs
Last active December 14, 2015 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrasKovacs/5025609 to your computer and use it in GitHub Desktop.
Save AndrasKovacs/5025609 to your computer and use it in GitHub Desktop.
Small brute Sudoku solver. The input is a flattened 9x9 table as a string where "0" denotes an empty cell. O/O2 compilation is advised for good performance. The solver may return multiple solutions (though a proper Sudoku table should be unambiguous).
import Data.Array.Unboxed
import Data.Array.Base (unsafeAt)
import Data.List.Split
import Data.List
type Table = UArray Int Char
solve :: String -> [String]
solve = map elems . go 0 . listArray (0, 80) where
rows = chunksOf 9 [0..80]
cols = transpose rows
blocks = chunksOf 9 . concat . concat . transpose . map (chunksOf 3) $ rows
pairs = [(x, delete x g) | g <- rows ++ cols ++ blocks, x <- g]
neighs = accumArray union [] (0, 80) pairs :: Array Int [Int]
go 81 table = [table :: Table]
go i table = case unsafeAt table i of
'0' -> concat [go (i + 1) (table // [(i, x)]) | x <- ['1'..'9'],
notElem x . map (unsafeAt table) $ unsafeAt neighs i]
_ -> go (i + 1) table
table = concat [
"480006902",
"002008001",
"900370060",
"840010200",
"003704100",
"001060049",
"020085007",
"700900600",
"609200018"]
main = print $ solve table
--487156932362498751915372864846519273593724186271863549124685397738941625659237418
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment