day 4
Signed-off-by: Jack Bond-Preston <jackbondpreston@outlook.com>
This commit is contained in:
parent
70eb8d1848
commit
4c287b2916
88
4/4.hs
Normal file
88
4/4.hs
Normal file
@ -0,0 +1,88 @@
|
||||
import System.IO
|
||||
import Text.Parsec
|
||||
import Text.Parsec.String
|
||||
import Control.Monad
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
|
||||
int :: Parser Int
|
||||
int = read <$> many1 digit
|
||||
|
||||
eol :: Parser ()
|
||||
eol = void $ char '\n'
|
||||
|
||||
draws :: Parser [Int]
|
||||
draws = int `sepBy1` char ','
|
||||
|
||||
boardRow :: Parser [Int]
|
||||
boardRow = do
|
||||
many (char ' ')
|
||||
int `sepBy1` many (char ' ')
|
||||
|
||||
board :: Parser [[Int]]
|
||||
board = boardRow `endBy1` eol
|
||||
|
||||
boards :: Parser [[[Int]]]
|
||||
boards = board `endBy1` (eol <|> eof)
|
||||
|
||||
inputParser :: Parser ([Int], [[[Int]]])
|
||||
inputParser = do
|
||||
d <- draws
|
||||
eol
|
||||
eol
|
||||
b <- boards
|
||||
|
||||
return (d, b)
|
||||
|
||||
checkRow :: [Int] -> [Int] -> Bool
|
||||
checkRow row drawn = all (`elem` drawn) row
|
||||
|
||||
checkBoard :: [[Int]] -> [Int] -> Bool
|
||||
checkBoard board drawn = any (`checkRow` drawn) board || any (`checkRow` drawn) (transpose board)
|
||||
|
||||
checkBoards :: [[[Int]]] -> [Int] -> [Bool]
|
||||
checkBoards boards drawn = map (`checkBoard` drawn) boards
|
||||
|
||||
processTurns :: [[[Int]]] -> [Int] -> [[Bool]]
|
||||
processTurns boards draws = map (checkBoards boards) turns
|
||||
where turns = [ take n draws | n <- [1 .. length draws ] ]
|
||||
|
||||
|
||||
-- ret: (turn no, board win states)
|
||||
getWinner :: [[[Int]]] -> [Int] -> (Int, Int)
|
||||
getWinner boards draws = (turnNo, winnerIndex)
|
||||
where results = processTurns boards draws
|
||||
turnNo = fromJust (findIndex or results)
|
||||
boardStates = fromJust (find or results)
|
||||
winnerIndex = fromJust (elemIndex True boardStates)
|
||||
|
||||
getLoser :: [[[Int]]] -> [Int] -> (Int, Int)
|
||||
getLoser boards draws = (turnNo, loserIndex)
|
||||
where results = processTurns boards draws
|
||||
turnNo = fromJust (findIndex and results)
|
||||
boardStates = results!!(turnNo - 1)
|
||||
loserIndex = fromJust (elemIndex False boardStates)
|
||||
|
||||
getFinalDraw :: [Int] -> Int -> Int
|
||||
getFinalDraw draws turnNo = draws!!turnNo
|
||||
|
||||
sumUnmarked :: [[Int]] -> [Int] -> Int
|
||||
sumUnmarked board draws = sum filtered
|
||||
where filtered = [ x | xs <- board,
|
||||
x <- xs,
|
||||
x `notElem` draws ]
|
||||
|
||||
main = do
|
||||
handle <- openFile "input.txt" ReadMode
|
||||
contents <- hGetContents handle
|
||||
case parse inputParser "" contents of
|
||||
Left x -> print x
|
||||
Right (draws, boards) -> print (finalDraw, unmarkedSum, finalDraw * unmarkedSum,
|
||||
finalDrawLose, unmarkedSumLose, finalDrawLose * unmarkedSumLose)
|
||||
where (turnNo, winnerIndex) = getWinner boards draws
|
||||
finalDraw = getFinalDraw draws turnNo
|
||||
unmarkedSum = sumUnmarked (boards!!winnerIndex) (take (turnNo + 1) draws)
|
||||
(turnNoLose, loserIndex) = getLoser boards draws
|
||||
finalDrawLose = getFinalDraw draws turnNoLose
|
||||
unmarkedSumLose = sumUnmarked (boards!!loserIndex) (take (turnNoLose + 1) draws)
|
||||
hClose handle
|
Loading…
Reference in New Issue
Block a user