90 lines
2.3 KiB
Haskell
90 lines
2.3 KiB
Haskell
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
|
|
|