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