Skip to content

Instantly share code, notes, and snippets.

@jdiez17
Created May 28, 2014 20:23
Show Gist options
  • Save jdiez17/25137e998dc31cdd81a7 to your computer and use it in GitHub Desktop.
Save jdiez17/25137e998dc31cdd81a7 to your computer and use it in GitHub Desktop.
module Sudoku where
import Data.List (intersperse, nub, transpose, (\\))
import Control.Applicative ((<$>))
import Control.Monad (sequence, mapM, guard)
data Position = Position Int Int
{- D0 is "Unknown" -}
data Digit = D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9
deriving (Eq, Ord, Read, Enum)
mkDigit :: (Integral a, Ord a) => a -> Maybe Digit
mkDigit n
| n >= 0 && n < 10 = Just $ toEnum $ fromIntegral n
| otherwise = Nothing
instance Show Digit where show x = show $ fromEnum x
newtype Sudoku = Sudoku { toList :: [[Digit]] }
instance Show Sudoku where
show sudoku = concat $ intersperse "\n" $ map show list
where list = toList sudoku
mkSudoku :: (Integral a) => [[a]] -> Maybe Sudoku
mkSudoku xss = if isSudoku then buildSudoku else Nothing
where
isSudoku :: Bool
isSudoku = outerLength == 9 && (all (== outerLength) $ map length xss)
where outerLength = length xss
toDigits :: Maybe [[Digit]]
toDigits = let listOfMaybes = [map mkDigit y | y <- xss]
in mapM sequence $ listOfMaybes
buildSudoku :: Maybe Sudoku
buildSudoku = Sudoku <$> toDigits
itemsInSquare :: Sudoku -> Position -> [Digit]
itemsInSquare (Sudoku rows) (Position x y) = [D1]
findNextPostion :: Sudoku -> [([Digit], Position)]
findNextPostion (Sudoku rows) =
do
x <- [0..8]
y <- [0..8]
guard $ (rows !! x !! y) == D0
let validMovesForPos = validMoves x y
guard $ length validMovesForPos > 0
return (validMovesForPos, (Position x y))
where
validMoves :: Int -> Int -> [Digit]
validMoves x y = [D0 ..] \\ (nub $ (rows !! x ++ columns !! y))
columns = transpose rows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment