Skip to content

Instantly share code, notes, and snippets.

@zlqhem
Created April 17, 2013 01:17
Show Gist options
  • Save zlqhem/5401035 to your computer and use it in GitHub Desktop.
Save zlqhem/5401035 to your computer and use it in GitHub Desktop.
import Data.List
import Data.Char
import Control.Monad
-- transpose
input="A-small-practice.in"
data Result = WinX | WinO | Draw | DontKnow deriving (Show, Eq)
type Board = [String]
whoWin :: Board -> Result
whoWin b
| isXwin $ possibleSeq b = WinX
| isOwin $ possibleSeq b = WinO
| hasEmpty b = DontKnow
| otherwise = Draw
isXwin xs = or [isWin 'X' seq | seq <- xs]
isOwin xs = or [isWin 'O' seq | seq <- xs]
isWin who seq = and [ch == who || ch == 'T' | ch <- seq]
hasEmpty b = or [ ch == '.' | ch <- foldl (++) "" b ]
possibleSeq b = b++transpose b++[crossDown b]++[crossUp b]
-- (0,0):(1,1):(2,2):(3,3)
crossDown b = (b !! 0 !! 0):(b !! 1 !! 1):(b !! 2 !! 2):(b !! 3 !! 3):[]
-- (0,3):(1,2):(2,1):(3,0)
crossUp b = (b !! 0 !! 3):(b !! 1 !! 2):(b !! 2 !! 1):(b !! 3 !! 0):[]
main = do
s <- readFile input
let isNumberStr xs = and [isDigit x | x <- xs]
let flattenBoards = let (head:xs) = filter (/= "") (lines s) in
if isNumberStr head then xs else (head:xs)
let boards = toBoards flattenBoards
zipWithM_ (\count board -> print (judge count board)) [1..] boards
toBoards [] = []
toBoards flattenBoards = [take 4 flattenBoards] ++ (toBoards $ drop 4 flattenBoards)
judge count board =
let r = case whoWin board of
WinX -> "X won"
WinO -> "O won"
Draw -> "Draw"
DontKnow -> "Game has not completed"
in "Case #" ++ show count ++ ": " ++ r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment