data Item = Rock | Paper | Scissors deriving (Eq, Show) readItem :: String -> Item readItem "A" = Rock readItem "B" = Paper readItem "C" = Scissors readItem "X" = Rock readItem "Y" = Paper readItem "Z" = Scissors wins :: Item -> Item -> Bool wins Rock Scissors = True wins Scissors Paper = True wins Paper Rock = True wins _ _ = False scoreItem :: Item -> Int scoreItem Rock = 1 scoreItem Paper = 2 scoreItem Scissors = 3 scoreWin :: Item -> Item -> Int scoreWin me you | me `wins` you = 6 | me == you = 3 | otherwise = 0 score :: Item -> Item -> Int score me you = scoreWin me you + scoreItem me scoreLine1 :: String -> Int scoreLine1 s = score me you where [you, me] = map readItem (words s) whatToPlay :: Item -> Int -> Item whatToPlay you score = head $ filter f all where all = [Rock, Paper, Scissors] f me = scoreWin me you == score neededScore "X" = 0 neededScore "Y" = 3 neededScore "Z" = 6 scoreLine2 :: String -> Int scoreLine2 s = score me you where [you', goal'] = words s (you, goal) = (readItem you', neededScore goal') me = whatToPlay you goal main :: IO () main = do input <- lines <$> getContents putStr "part 1: " print $ sum $ map scoreLine1 input putStr "part 2: " print $ sum $ map scoreLine2 input