Skip to content

Instantly share code, notes, and snippets.

@skatenerd
Created December 2, 2023 18:31
Show Gist options
  • Save skatenerd/5d5029dc2b8cafcddebb74bb1ddb78bb to your computer and use it in GitHub Desktop.
Save skatenerd/5d5029dc2b8cafcddebb74bb1ddb78bb to your computer and use it in GitHub Desktop.
2023 Day Two
{-# LANGUAGE OverloadedStrings #-}
module DayTwo
( partOne, greenCount, legalDraw, legalGame, partOneCheckRow, gameId, power, partTwo
) where
import qualified Data.Text as T
import qualified Data.List.Safe as LS
import qualified Data.Text.IO as TI
partOne :: IO ()
partOne = do
fileBody <- TI.readFile "/home/me/Downloads/input.txt"
let allLines = T.lines fileBody
legalGames = filter partOneCheckRow allLines
answer = sum $ map gameId legalGames
print answer
partTwo :: IO ()
partTwo = do
fileBody <- TI.readFile "/home/me/Downloads/input.txt"
let allLines = T.lines fileBody
answer = sum $ map power allLines
print answer
maybeToInt :: (Maybe Int) -> Int
maybeToInt Nothing = 0
maybeToInt (Just n) = n
draws = T.split (== ';')
colorCount :: T.Text -> T.Text -> Int
colorCount target draw = maybeToInt asMaybe
where splitted = T.split (== ' ') $ T.filter (/= ',') draw
asMaybe = do
colorIdx <- LS.elemIndex target splitted
amountString <- splitted LS.!! (colorIdx - 1)
return $ read $ T.unpack amountString
greenCount = colorCount "green"
blueCount = colorCount "blue"
redCount = colorCount "red"
minimumLegalColorCount color game = maximum $ map (colorCount color) $ draws game
minimumLegalGreenCount = minimumLegalColorCount "green"
minimumLegalRedCount = minimumLegalColorCount "red"
minimumLegalBlueCount = minimumLegalColorCount "blue"
power game = (minimumLegalGreenCount game) * (minimumLegalRedCount game) * (minimumLegalBlueCount game)
legalDraw maxRed maxGreen maxBlue draw = (greenCount draw <= maxGreen) && (redCount draw <= maxRed) && (blueCount draw <= maxBlue)
legalGame maxRed maxGreen maxBlue game = Prelude.all (legalDraw maxRed maxGreen maxBlue) (draws game)
partOneCheckRow = legalGame 12 13 14
gameId :: T.Text -> Integer
gameId game = read $ T.unpack $ splitted Prelude.!! 1
where splitted = T.split (== ' ') noColons
noColons = T.filter (/= ':') game
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment