Skip to content

Instantly share code, notes, and snippets.

@skatenerd
Created December 2, 2022 23:43
Show Gist options
  • Save skatenerd/c03dc58dbbf4835b6f40c79918740aec to your computer and use it in GitHub Desktop.
Save skatenerd/c03dc58dbbf4835b6f40c79918740aec to your computer and use it in GitHub Desktop.
AOC 2022 Day 2
module DayTwo (partOne, partTwo) where
import qualified Data.Text as T
import qualified Data.Text.IO as TI
import qualified Data.Maybe as M
import qualified Data.List as L
data Outcome = Win | Loss | Tie deriving (Eq, Show)
data Move = Rock | Paper | Scissor deriving (Eq, Show)
data Game = PartOneGame { us :: Move, them :: Move } |
PartTwoGame { requiredOutcome :: Outcome, them :: Move } deriving (Eq, Show)
playMatch :: Move -> Move -> Outcome
playMatch Rock Scissor = Win
playMatch Paper Rock = Win
playMatch Scissor Paper = Win
playMatch ourMatchMove theirMatchMove = if ourMatchMove == theirMatchMove then Tie else Loss
scoreRound :: Num a => Game -> a
scoreRound PartOneGame{us=ourMove, them=theirMove} = (scoreShape ourMove) + (scoreOutcome $ playMatch ourMove theirMove)
where
scoreOutcome Win = 6
scoreOutcome Tie = 3
scoreOutcome Loss = 0
scoreShape Rock = 1
scoreShape Paper = 2
scoreShape Scissor = 3
scoreRound PartTwoGame{requiredOutcome=outcome, them=theirMove} = scoreRound $ PartOneGame { us=requiredMove, them=theirMove}
where
requiredToWinAgainst x = M.fromJust $ L.find (\candidate -> (playMatch candidate x) == Win) allMoves
requiredToLoseAgainst x = M.fromJust $ L.find (\candidate -> (playMatch candidate x) == Loss) allMoves
getRequiredMove Win = requiredToWinAgainst theirMove
getRequiredMove Loss = requiredToLoseAgainst theirMove
getRequiredMove Tie = theirMove
requiredMove = getRequiredMove outcome
allMoves = [Rock, Paper, Scissor]
parse :: T.Text -> Maybe Game
parse row = do
theirMove <- charToMove $ (T.unpack row) !! 0
ourMove <- charToMove $ (T.unpack row) !! 2
return $ PartOneGame ourMove theirMove
where
charToMove 'A' = Just Rock
charToMove 'B' = Just Paper
charToMove 'C' = Just Scissor
charToMove 'X' = Just Rock
charToMove 'Y' = Just Paper
charToMove 'Z' = Just Scissor
charToMove _ = Nothing
parsePartTwo :: T.Text -> Maybe Game
parsePartTwo row = do
theirMove <- charToMove $ (T.unpack row) !! 0
outcome <- charToOutcome $ (T.unpack row) !! 2
return $ PartTwoGame { requiredOutcome = outcome, them = theirMove }
where
charToMove 'A' = Just Rock
charToMove 'B' = Just Paper
charToMove 'C' = Just Scissor
charToMove _ = Nothing
charToOutcome 'X' = Just Loss
charToOutcome 'Y' = Just Tie
charToOutcome 'Z' = Just Win
charToOutcome _ = Nothing
partOne :: IO Integer
partOne = do
input <- TI.readFile "/users/wailee.feman/Downloads/input.txt"
let inputLines = T.lines input
games = M.catMaybes $ map parse inputLines
answer = sum $ map scoreRound games
return answer
partTwo :: IO Integer
partTwo = do
input <- TI.readFile "/path/to/input.txt"
let inputLines = T.lines input
games = M.catMaybes $ map parsePartTwo inputLines
answer = sum $ map scoreRound games
return answer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment