adventofcode/2022/app/Day2/Main.hs

90 lines
2.3 KiB
Haskell
Raw Normal View History

2022-12-02 20:19:24 +01:00
module Day2.Main (main) where
import Data.List
import Data.Tuple
import Data.Maybe
import System.IO
import Control.Monad
main :: IO ()
main = do
putStrLn "Day 2"
handle <- openFile "app/Day2/input" ReadMode
contents <- hGetContents handle
let r1 = part1 contents
putStrLn $ "part 1: " ++ show r1
let r2 = part2 contents
putStrLn $ "part 2: " ++ show r2
data Shape = Rock | Paper | Scissors
deriving (Show, Eq)
instance Read Shape where
readsPrec _ "A" = [(Rock, "")]
readsPrec _ "B" = [(Paper, "")]
readsPrec _ "C" = [(Scissors, "")]
readsPrec _ "X" = [(Rock, "")]
readsPrec _ "Y" = [(Paper, "")]
readsPrec _ "Z" = [(Scissors, "")]
readsPrec _ _ = []
instance Enum Shape where
fromEnum Rock = 1
fromEnum Paper = 2
fromEnum Scissors = 3
toEnum _ = error "nope"
data Result = Loss | Tie | Win
deriving (Show, Eq)
instance Read Result where
readsPrec _ "X" = [(Loss, "")]
readsPrec _ "Y" = [(Tie, "")]
readsPrec _ "Z" = [(Win, "")]
readsPrec _ _ = []
instance Enum Result where
fromEnum Loss = 0
fromEnum Tie = 3
fromEnum Win = 6
toEnum _ = error "nope"
result :: Shape -> Shape -> Result
result a b | a == b = Tie
result Rock Paper = Loss
result Rock Scissors = Win
result Paper Rock = Win
result Paper Scissors = Loss
result Scissors Rock = Loss
result Scissors Paper = Win
parseInput :: String -> (String -> a) -> (String -> b) -> [(a, b)]
parseInput contents lhs rhs = shapes
where
rounds = lines contents
picks = map (\l -> ([l !! 0], [l !! 2])) rounds
shapes = map (\(a,b) -> (lhs a, rhs b)) picks
part1 :: String -> Int
part1 contents = sum scoresResults + sum scoresPicks
where
rounds = parseInput contents (read :: String -> Shape) (read :: String -> Shape)
scoresResults = map (fromEnum . (uncurry result) . swap) rounds
scoresPicks = map (fromEnum . snd) rounds
part2 :: String -> Int
part2 contents = sum solutions + sum outcomes
where
rounds = parseInput contents (read :: String -> Shape) (read :: String -> Result)
getResult o r = fromJust $ find (\p -> result p o == r) [Rock,Paper,Scissors]
solutions = map (fromEnum . uncurry getResult) rounds
outcomes = map (fromEnum . snd) rounds