From 71972e30ecda4faa318c0037e5677bb889c737a3 Mon Sep 17 00:00:00 2001 From: Jens Kadenbach Date: Fri, 2 Dec 2022 16:18:26 +0100 Subject: [PATCH] Day 2 --- aoc2022.cabal | 3 + ressources/day02-input | 2500 ++++++++++++++++++++++++++++++++++++++++ src/Day2.hs | 16 + src/Day2/Part1.hs | 31 + src/Day2/Part2.hs | 42 + src/Day2/Shared.hs | 58 + src/Lib.hs | 4 +- test/Day2Spec.hs | 45 + 8 files changed, 2697 insertions(+), 2 deletions(-) create mode 100644 ressources/day02-input create mode 100644 src/Day2.hs create mode 100644 src/Day2/Part1.hs create mode 100644 src/Day2/Part2.hs create mode 100644 src/Day2/Shared.hs create mode 100644 test/Day2Spec.hs diff --git a/aoc2022.cabal b/aoc2022.cabal index 91b52ee..5368e0c 100644 --- a/aoc2022.cabal +++ b/aoc2022.cabal @@ -28,6 +28,9 @@ library Day1 Day1.Internal Day2 + Day2.Part1 + Day2.Part2 + Day2.Shared Lib other-modules: Paths_aoc2022 diff --git a/ressources/day02-input b/ressources/day02-input new file mode 100644 index 0000000..7507561 --- /dev/null +++ b/ressources/day02-input @@ -0,0 +1,2500 @@ +C X +C X +C X +A Z +C X +C Z +C X +B Y +C X +C X +C X +B Y +C X +B Z +C Z +C X +C X +C Z +C Z +B Y +C Z +C X +B Z +C X +C X +C X +B Y +C Z +B Z +C X +B Y +C Z +A Y +C X +B Y +A Y +C X +C Y +C X +C Z +C X +C X +A Y +C X +C X +B Y +B Y +C X +C X +B Y +C Z +B Y +B Y +C X +C X +C Y +B X +C X +C X +B X +C Y +B X +B Y +C X +C Z +B Y +B Y +B Y +B X +C Z +C X +B Y +C X +A Y +C Z +A Y +C Z +C X +C Z +B Y +B X +C X +B Z +C X +C Y +C X +C X +C Z +C Z +C Z +B Z +C Y +B Y +B Y +B Y +C X +B Y +C Z +C X +C X +C X +B Y +C Z +C X +C X +C X +C X +C X +B Z +C X +A Y +B X +C X +C X +C X +A Y +B Z +C X +C Z +C X +A Y +C X +B Y +C Z +C X +C Z +B Z +B Y +B Y +C Z +B Y +B Y +B X +B Y +B Y +C X +C Z +C X +C X +C X +C X +C X +C X +C X +C X +C Z +C Y +B Y +B Y +C Z +A X +C X +C Z +B Z +B Y +C Z +C X +C X +B Z +B Z +C X +C X +C X +B X +A Y +B X +C X +C Z +C X +C Z +B Y +C X +B Y +A Y +A Y +A Y +B Y +C X +C Y +B Y +A Y +C Z +A X +C X +C Z +C X +C X +C X +C Z +C X +B X +A X +C Z +C X +C X +C Y +C X +C Z +B Y +C X +C X +C X +C Z +C X +B X +C X +B Y +B X +C Y +C X +C X +C Y +C X +C X +C X +C X +B Y +C X +B X +B Y +C Y +C X +C X +B X +C X +C X +B Y +A Y +C Z +C X +B Y +C X +C X +C Z +C X +C X +A Z +C X +C Y +A Z +C Z +C Z +B Y +C X +B Y +C X +C X +C X +B Y +B Z +C X +C X +C X +B X +B Y +C X +A Y +B X +B X +B Y +B Z +C X +B X +C Z +C X +B Y +C X +A X +C Y +A Z +C X +A Z +B Z +C X +B X +B Y +A Y +B X +C X +B Y +B X +C Z +B Y +B X +A X +C Z +B Y +C X +C X +C X +A Y +B Y +C X +B Y +C Z +C X +C Z +B Z +B X +A Y +C X +B Y +C X +C X +C X +B Y +B Y +B Z +B Y +C Z +C X +C Z +C X +C Z +C X +C X +A Y +C Z +B Y +A Y +B Z +C X +C X +C X +C X +B Y +C X +C X +C X +C X +A Y +C X +C X +C X +C Z +C X +B Y +C X +C X +C Z +C X +C X +C X +B Y +B Z +B Y +C X +C X +C X +B Y +C X +B Y +C X +C X +C Z +C Y +C Z +C Z +C X +C X +C Z +A Y +C Z +C X +B Z +C X +C Z +C X +C X +B Y +B Z +B Z +A Y +B Z +C Z +C X +C Y +B Y +A Y +C X +A Y +A Z +B Z +A Y +C X +C Z +A Y +B Y +B Y +C X +C Z +B Y +C X +C X +B Y +C X +C Z +B Y +B X +C Z +C X +C Y +C X +C X +C X +C Y +C X +B Z +C Y +B Y +B Y +C X +A Y +C X +A Z +A Y +B X +C X +B Y +C X +B Y +B Y +C Z +C Z +A Y +C X +A Y +C Z +C X +C Z +C X +B Y +B X +C X +B X +C X +C X +B Y +C X +C X +C X +C Z +C Z +B Y +C Y +C X +C X +B Y +C X +C Z +C X +C Z +C X +C Y +C X +C Y +C Z +C X +B Y +C X +B X +B Y +C Z +B Y +B Z +B Z +C X +A X +C X +C Z +C Y +C X +B X +C Y +A Y +C Y +C X +B Y +B Y +C X +C Z +B X +A Y +C X +C X +C X +B Y +B Y +B Z +C Z +C Z +B X +C X +B Z +C X +B Y +B Y +C Z +C X +C Z +C X +C X +C X +C Z +C Z +C Z +C X +B Y +C X +C X +B Y +C X +C X +C X +A Y +C Z +B Z +B Z +C Z +C X +C Y +C X +A Y +C X +C X +C Z +C X +B Y +B Y +C X +C Z +C Y +B X +B Y +A Y +B Y +C X +C X +C Z +B Y +C X +C Y +C Y +A Z +B Y +C X +B X +A Y +B Y +B Y +C Z +A X +C X +A Y +C Z +C Z +B X +A Y +C Y +B Y +C X +A Y +B Y +C X +C X +A Y +B Y +C Z +C X +C Z +A X +A Z +C X +C Z +C X +C Y +C X +B Y +C Z +C X +B Y +C Z +C X +B Z +B X +C X +C X +B X +C X +C Z +C X +C X +C X +C Y +B X +C X +C X +B Y +B Y +C X +B Y +C X +C Z +C X +B Y +B Y +B Y +C Z +C X +A Z +A Y +C X +C Z +C Z +A Z +B Y +A Z +C Z +B Z +B Y +C X +B Y +C X +B Y +A Y +C X +C X +C X +C X +B Y +A Z +B X +C X +C X +C X +C Z +B Y +C X +B Y +B Y +B Y +C X +C Y +B Z +C X +B Y +B X +C X +C X +B Y +C X +B X +C X +C X +A Z +C X +A Z +C X +C X +C Z +C X +B Y +C Z +B Y +C X +B Y +C Z +B X +C X +A Y +C Y +C X +C X +B Y +B Y +C X +C Z +C Z +C Z +C X +C X +B Z +B Z +A Z +B Y +B Y +B Y +A X +C X +B X +B X +C X +C X +C X +C X +B X +B X +B Y +B Y +B Y +B X +C X +C Z +B Y +B Y +A Y +A Y +C X +C X +C X +B X +C Z +C X +C X +B Y +C X +C X +C X +C X +B X +B X +A Y +B Z +C Z +B Z +A X +C X +B X +C X +B Z +C Z +B X +B Y +C Z +C Y +C X +C X +C Z +C X +C X +C X +C Z +C X +B Y +C X +C X +C X +A Z +C Z +C X +C X +C X +C Y +A Y +C Z +B X +B X +C X +C X +C Z +A Y +C Z +C X +B Y +B Y +B Z +B Y +C X +B X +C X +C X +B Y +C Y +C Z +C X +C Z +B Y +C Y +B Y +B X +C Y +B X +C X +C X +B Z +C Y +B Y +B Y +B Z +C Y +B X +B Y +C Z +A Y +B Y +B Y +A Z +C X +C Z +B Z +C X +C X +B Y +C X +C X +B X +C X +C Z +C Z +B Y +B X +B Z +B Z +B X +C X +C X +C X +C X +B Y +A Y +B X +C X +C X +C X +B Y +C Z +B X +C Y +C Z +B Z +C X +C X +B Y +C Z +B Y +C X +C X +B Y +B X +C X +C X +C X +C X +B Y +A Y +C Y +C X +C X +B Y +B X +B Y +C X +C X +C Z +C X +C Z +A Y +C X +C Z +B Y +C Z +B X +A X +C X +C Z +C Y +B Y +C X +C Z +C Z +B X +C X +C X +C Z +C X +A Y +B Y +C X +C X +C X +C X +C X +C X +B X +B X +C Z +B Y +C X +C X +A Z +C X +C Z +B Y +C Z +C Y +C X +C Y +C X +C X +C Z +B Y +B Y +B Z +B Y +C Z +C X +C Z +B Y +C Z +C X +C X +C X +C Y +C X +C X +B X +C X +B Y +B X +B X +B Y +B Y +B Z +C Z +A Y +B X +B Y +C Z +C Y +C X +C X +C Z +A Y +C X +C Z +C X +B X +B Z +C Z +B Y +C X +C X +C Z +B X +B Y +C Z +B Z +B Z +C X +C X +C X +B Y +C X +C Z +C X +C X +B Y +C X +B Y +B Y +C X +C X +C X +B Y +B Z +C X +C X +B X +B Y +C X +C Y +B Y +A Y +C X +C X +C X +C Y +C X +C Z +A Y +B X +C Z +C X +C X +C X +B Y +B Y +C Z +C Z +C Y +C Z +C X +B Y +B Y +C X +B Y +C X +B Y +C X +C X +C X +C X +C Z +B Y +B Z +C X +C X +B Y +C X +B Y +C X +B Y +C Y +B Y +C X +B Y +C X +B Y +C X +B Z +C X +B X +B X +B Y +B X +B Z +C X +B Y +C X +B Z +B Y +C X +C Y +C Z +A Z +C X +C X +B Y +A X +C X +B Z +C Z +B X +C X +C X +B Y +B Z +A Z +A Z +C X +C X +C X +C X +A Y +B Y +B Y +C X +B Z +C Z +C X +C X +B Z +C Z +B Y +C Z +C Y +C Z +B Y +C Z +B Z +B Y +C X +C Z +C X +C X +C Y +C X +B X +A X +B X +C X +C Z +C Z +C Z +B Y +B X +C X +B Y +C X +C X +C X +A Y +C Z +A Y +C X +C X +C X +B Z +C X +C Z +C X +B Y +B Y +B X +C X +C Z +C Z +A Z +B Y +C Y +B Y +C Z +C X +A Z +C X +B X +B Z +C X +B Y +C Y +C X +B X +C Z +C Z +C Z +C X +C X +C X +A Y +C Z +B X +B X +B Y +B X +A Y +C X +B Y +C X +C X +C X +B X +A X +B Y +C X +C Z +B X +A X +C X +B Y +C X +C Z +A X +C X +B Z +C X +C Z +C Z +B Z +C Z +C X +B Y +C X +B Y +C Y +B Y +C Y +B Y +C X +B X +C Y +C X +C X +B Y +C Y +A Z +C X +C X +C X +C X +B Y +B Y +C X +C Z +C X +C X +C X +B Y +B Y +B Y +C X +B Y +B X +C Y +B Y +C X +C X +B Y +C X +C Y +C X +B Y +C X +B Y +C Z +C X +C X +C Z +C Z +B Z +C Z +C X +C X +C Z +C Z +B X +C Y +C Y +C X +C X +B Z +C Z +B Y +B Y +C Z +C X +C X +B Y +C X +C X +C Z +C X +C Z +A Z +B Y +C Z +C X +A X +A Z +B Y +B Y +B Y +B Y +C Z +B X +C X +B Y +B Y +C X +B Y +B Y +C Z +C X +B Y +C Y +C X +C Z +C X +A Y +C X +C X +C Z +A X +B Y +B Y +B Z +B Y +C Z +C X +C X +B Y +C X +C Z +C Z +C X +B X +C Z +C Z +B Y +B Y +C X +B Y +B X +C X +A Y +B Y +B Y +C X +C Z +B X +C X +C Z +A Z +B Y +C X +C Z +C X +C X +C X +B Y +B X +B Y +B X +C X +C X +C Z +C X +C X +C X +C X +B Y +C X +B Y +C Z +B X +C Z +C X +B Z +C X +A Y +C X +C X +C X +C X +C X +C X +B Y +C X +C X +B Y +C Z +C Z +B X +C X +A X +C X +C X +B X +C Z +B Y +B X +C X +C X +B Y +C Z +C Y +B Y +C Y +B X +C X +B Y +C X +C Z +C Z +B Y +B Y +A Z +B X +C X +C X +C Z +C X +C X +B X +C Z +A Y +C Z +C X +C Z +C X +C Z +C Z +A Z +A Y +A Y +C Z +C X +A X +C X +B Y +B Y +C X +C Z +B X +B Z +C X +C Z +B Y +C Z +B Y +C Z +B Z +B Y +C X +C X +B Y +C X +C X +C Z +B X +C Z +C Z +B Y +A Z +C X +B Y +C X +C Z +C X +C X +B Y +C Z +A Z +C X +C X +B X +C X +C X +B Z +B Y +B Y +B X +C Y +C X +B Y +B Y +C X +C X +C X +A Z +C Z +A Y +C X +B Y +B Y +C X +C Z +C X +C X +B X +B Y +C Z +B Z +C Y +C X +C X +B Z +B X +C Z +C X +C X +C X +C X +C X +C X +C X +C X +B Y +C Y +C X +B Y +B Y +B Y +C X +C X +B X +C Y +B Y +C X +B Z +C X +C X +B Z +C Z +B X +B Z +C Z +B Z +C X +B Y +C X +C Y +A Y +B X +B Y +B Z +C X +B Z +A Y +C Z +C Z +C Y +B Y +B Y +B Z +C X +C X +A Y +C Z +C X +C X +C X +C Z +C X +C X +C X +C X +A Y +C X +C Z +C Z +C X +B Z +C X +C X +A Y +B Z +C Y +A X +C X +C X +C Z +C X +C X +C X +A Y +A Y +C Z +B Z +B X +C X +C X +C X +A Z +B Y +C Z +C Z +C X +C X +C Z +C X +B Y +B X +C Z +C X +B Y +B Z +C X +C X +B Y +C Z +C Z +C X +B Y +C X +C X +B Y +A Z +B X +C X +C X +C X +B Y +C X +C Z +B Y +B X +C Z +B Y +B X +C X +C X +A Y +C Z +C X +C X +C Z +B Z +B Y +B Y +B Z +C X +A Y +B X +C X +C X +B Y +C X +C Z +B Y +C X +C X +C X +C Y +B Y +B X +B Y +C X +C X +C Z +C Z +A Y +C X +C Y +B Y +B Y +B X +C X +C X +B X +C X +C X +C X +B X +C X +C Z +C X +A X +B Y +C Z +B Y +C Z +C X +C Z +C X +B Y +C X +B X +A X +A Z +C X +C Z +C X +C X +B Y +B X +B X +B Y +B Z +C Z +C X +C Z +B X +C X +B Y +B X +B Y +B Y +C Y +C X +B X +B Y +C X +C Z +C X +B Y +C X +C X +B Y +C X +C X +C Z +C X +B Z +A X +C X +C X +B X +C Y +C X +B Y +C X +C X +A Y +A X +C X +B Z +C X +A X +C X +C Y +C X +C X +C X +C Y +C X +C X +B Z +C X +C X +B X +B X +C X +C X +B Z +C X +A Y +B X +B Y +C X +C X +B X +B Y +C Z +B X +B Y +C X +C X +C X +C Z +C X +C X +C X +A Y +A Z +C Z +A Y +B Y +B Y +C Y +C X +C Y +C X +B Y +C X +C Z +A Y +B X +C Z +B Z +C Z +A Z +A X +B Y +B Y +C X +C Y +B Y +B Y +B Y +C Y +C X +B Y +B Y +C X +C X +B Y +C X +B Y +B Y +C Y +C Y +A Y +B Y +B Y +C X +B X +B X +C X +B Y +A X +C Z +C Z +C X +A X +B Y +C Y +B Y +C Z +C Z +B Y +B X +B Y +B X +B X +C Y +C Y +B Z +B Y +C X +C X +C Y +C X +C X +C X +C Z +B Y +B Y +C X +C X +C Z +B Y +A Y +B Y +B Y +B X +C X +C Z +C X +C Z +C X +B Z +C Z +C X +B Y +A Y +C X +A Y +B Y +C Y +A X +C X +B Z +C X +B Y +A Z +C X +C Z +C Z +C X +A Y +C Z +C X +C X +B Y +C Z +B Z +B Y +B Y +C Z +A Y +C X +B X +C Z +C X +B Y +A Y +B Y +B Y +C X +C Y +B Z +B Y +B X +C Z +C X +C X +B Y +A Y +B Y +C X +C X +B Y +B Y +C X +C Z +C X +B Y +C X +B Y +B Y +C X +C Z +A Z +B X +C Z +B X +C X +C Z +B Y +B Z +C X +B Y +C Z +C X +C X +C X +B Z +C X +C Z +C X +C X +B Y +B Y +C X +A X +A X +C X +C X +B X +C X +C Z +B Y +C Z +C Z +C X +A Y +A Z +C X +C X +B Y +B Y +B Y +C Z +B Y +C X +C X +C X +B X +B Y +B X +B Y +A Y +C X +B X +C X +C Y +C Z +C Y +C Z +C X +A Y +C X +B Y +C Z +C Z +C X +B Y +B Y +B Y +C X +A X +C X +B X +C Y +C X +B Y +C Z +C X +C Z +C Z +C Z +A Y +B Y +B Y +C X +A Y +C Y +B Y +C X +B Z +B Y +C X +B Y +C Z +B Y +C Z +C X +B Z +C Z +C Z +B X +C X +C Y +B X +B Y +C X +A X +B Y +C Z +B Y +C X +C X +B X +C X +B Y +C X +B Y +C Z +C Z +C X +C X +A Y +B Y +C Y +B Y +B Y +B Y +C X +C Y +A X +A Y +C X +C X +B X +B Y +C X +C Z +C X +B Y +C X +C Y +B Z +B X +C X +A Y +C X +C Y +C Z +B X +C X +C Z +C Y +C X +C Z +C X +C Z +B Y +B Z +C X +A Y +C X +C X +B X +B Y +C X +C X +B Y +C X +B Z +C X +C X +C X +B Z +A Y +B X +B Y +B Y +B Y +B Y +C X +C Z +B Z +C Z +C X +B Y +C X +B Y +A Y +C Y +B X +B Z +C X +C X +C X +A Y +B X +B Z +C X +C Z +B Y +C Z +C X +B Y +B Z +C Y +C Y +C X +C X +B Z +B Y +A Y +C Z +B Y +B Y +A Z +C X +B Y +A Y +C X +C Z +B Y +C X +A Z +C X +B Z +B Y +C Z +B Y +C X +B X +B Y +C X +B Y +C X +C Y +B Y +B X +C X +C Y +C X +B Y +C Y +C X +C X +B Y +B Y +B X +C X +B X +A Y +C X +B Y +C Y +C Z +C X +B Z +B X +C X +C X +C Z +C Z +B Y +C X +C X +B Y +C X +C X +A Y +C Z +C X +A X +B Y +C X +C X +C X +C Z +B Y +C X +B Y +B Z +C X +C X +B Y +A Z +C X +C X +C X +A Y +B Y +C X +C Y +C Z +A X +C X +C X +B X +B Y +C X +B Y +B X +B X +C X +C Z +B Y +B Y +C Z +B Y +A Y +C X +B Y +C X +C Z +C X +C Z +A Y +C X +B Z +C Z +B Z +C Z +C X +B Y +A Z +C X +C Z +B Y +B Y +C X +C Z +A X +B X +B Y +C X +C X +B Z +C X +C X +C Z +A Y +C X +A X +C X +C X +B X +C Z +B Y +B Y +C Z +B Y +B Y +C X +C X +B Z +B Y +B Y +C X +A X +C X +B Y +C X +B Y +C Z +A Z +C X +C Z +C Y +B Y +C X +C Z +C Z +B Y +B Z +B X +C Z +C Z +B Z +B Z +B Y +C X +B Y +B Y +B X +B Y +C X +C Z +C Z +B Y +B Y +B Z +C X +C Z +C Z +C Z +C X +C X +B Y +C X +B Y +B Y +C Y +C X +B Y +C X +C X +C X +C Z +A Z +C X +A X +A Y +B Y +C X +B Y +B Y +C Y +C X +C X +C X +B Y +C X +A Y +B Y +C Z +C Z +C X +A Y +C X +B Y +C X +C Z +C Z +C Y +B Y +C X +B Y +B Y +C Y +C X +B X +C Z +C X +C X +C X +B Y +B Z +C Z +C X +C Z +B Y +A Z +C X +C Z +B Z +A Z +B Y +B Y +C X +C Z +C X +C X +C X +C X +C Z +C X +B Y +C Y +B Y +C X +C Z +B Z +B X +C Y +C X +B Y +C X +B X +C X +C X +C Z +C X +B Y +C X +C Z +C Z +B X +C X +B Y +C X +B Y +B X +C X +A Y +C X +C X +C Z +B Y +C X +B Z +C X +C X +C X +C X +B Z +C X +B Y +C X +B X +C Z +C X +B Y +C X +C X +C X +A Y +B Z +C Z +A Z +C X +B X +C Z +C Y +B Z +C X +B Y +B Z +C X +C Z +B X +C X +C Z +C X +B Y +B X +B Y +B Y +C Y +C Y +C Y +C X +B Y +B Y +C X +C X +C Y +B Y +C X +C X +C Z +C X +B X +C X +C Y +C X +C X +C X +C Z +C Z +C Y +C Z +C Z +B X +C X +C X +B Y +C X +C X +C Z +B Y +C X +C X +C X +A Y +A X +C Z +C Z +C X +C X +B X +B Y +C X +C Y +B Y +B Y +C X +C Z +C X +C Z +B X +C X +C X +B Y +B Y +B Y +C X +C X +C X +C Z +C X +C X +B Z +C X +C Y +C X +A Y +C X +C X +B X +C X +C X +B Z +C X +C X +C Z +C Z +C X +C Y +C X +C X +C X +C X +B Y +C X +C Y +C Z +C X +C X +C X +C X +B Y +B X +C X +C X +C Y +C X +B Y +C X +C X +C Z +C Z +C X diff --git a/src/Day2.hs b/src/Day2.hs new file mode 100644 index 0000000..3e96aa6 --- /dev/null +++ b/src/Day2.hs @@ -0,0 +1,16 @@ +module Day2 ( + day2 +) where + +import Day2.Part1 +import Day2.Part2 + +day2 :: IO () +day2 = do + input <- readFile "ressources/day02-input" + putStrLn "Day1" + let score1 = day2_1 input + putStrLn ("Score of all games: " ++ show score1) + let score2 = day2_2 input + putStrLn ("Score of all games according to plan: " ++ show score2) + return () diff --git a/src/Day2/Part1.hs b/src/Day2/Part1.hs new file mode 100644 index 0000000..41be6b3 --- /dev/null +++ b/src/Day2/Part1.hs @@ -0,0 +1,31 @@ +module Day2.Part1 ( +parseGameList, +readGame, +playGames, +day2_1 +) where + +import Day2.Shared + +parseGameList :: String -> [Game] +parseGameList = map readGame . lines + +readGame :: String -> Game +readGame [x, ' ', y] = Game (opponent x, me y) + where + opponent 'A' = Rock + opponent 'B' = Paper + opponent 'C' = Scissors + opponent _ = error $ "unknown opponent shape: " ++ [x] + me 'X' = Rock + me 'Y' = Paper + me 'Z' = Scissors + me _ = error $ "unknown me shape: " ++ [x] +readGame xs = error $ "readGame not implemented for " ++ xs + +playGames :: [Game] -> Score +playGames = foldMap play + +day2_1 :: String -> Score +day2_1 = playGames . parseGameList + diff --git a/src/Day2/Part2.hs b/src/Day2/Part2.hs new file mode 100644 index 0000000..2cac24c --- /dev/null +++ b/src/Day2/Part2.hs @@ -0,0 +1,42 @@ +module Day2.Part2 ( +day2_2, +readGameHints, +GameHint (GameHint), +Outcome (Win, Draw, Lose), +executePlan +) where + +import Day2.Shared + +data Outcome = Win | Draw | Lose deriving (Show, Eq) + +newtype GameHint = GameHint (Shape, Outcome) deriving (Show, Eq) + +readGameHints :: String -> [GameHint] +readGameHints = map parseGameHint . lines + +parseGameHint :: String -> GameHint +parseGameHint [x, ' ', y] = GameHint (opponent x, me y) + where + opponent 'A' = Rock + opponent 'B' = Paper + opponent 'C' = Scissors + opponent _ = error $ "unknown shape: " ++ [x] + me 'X' = Lose + me 'Y' = Draw + me 'Z' = Win + me _ = error $ "unknown game result: " ++ [x] +parseGameHint xs = error $ "readGameHint not implemented for " ++ xs + +playGames :: [GameHint] -> Score +playGames = foldMap (play . executePlan) + +executePlan :: GameHint -> Game +executePlan (GameHint (x, Draw)) = Game (x, x) +executePlan (GameHint (x, Win)) = Game (x, winAgainst x) +executePlan (GameHint (x, Lose)) = Game (x, loseAgainst x) + + +day2_2 :: String -> Score +day2_2 = playGames . readGameHints + diff --git a/src/Day2/Shared.hs b/src/Day2/Shared.hs new file mode 100644 index 0000000..4bf348f --- /dev/null +++ b/src/Day2/Shared.hs @@ -0,0 +1,58 @@ +module Day2.Shared ( + Shape (Rock, Paper, Scissors), + shapeScore, + Score (Score), + Game (Game), + gameWin, + gameLoss, + gameDraw, + play, + winAgainst, + loseAgainst +) where + +data Shape = Rock | Paper | Scissors + deriving (Show, Eq) + +newtype Score = Score Int + deriving (Show, Eq) + +instance Semigroup Score where + (<>) (Score x) (Score y) = Score (x + y) + +instance Monoid Score where + mempty = Score 0 + +gameWin :: Score +gameWin = Score 6 + +gameDraw :: Score +gameDraw = Score 3 + +gameLoss :: Score +gameLoss = Score 0 + +newtype Game = Game (Shape, Shape) + deriving (Show, Eq) + +shapeScore :: Shape -> Score +shapeScore Rock = Score 1 +shapeScore Paper = Score 2 +shapeScore Scissors = Score 3 + +winAgainst :: Shape -> Shape +winAgainst Rock = Paper +winAgainst Paper = Scissors +winAgainst Scissors = Rock + +loseAgainst :: Shape -> Shape +loseAgainst Rock = Scissors +loseAgainst Paper = Rock +loseAgainst Scissors = Paper + + +play :: Game -> Score +play (Game (x, y)) + | winAgainst x == y = gameWin <> shapeScore y + | loseAgainst x == y = gameLoss <> shapeScore y + | otherwise = gameDraw <> shapeScore y diff --git a/src/Lib.hs b/src/Lib.hs index dce638b..1a619a9 100644 --- a/src/Lib.hs +++ b/src/Lib.hs @@ -2,8 +2,8 @@ module Lib ( someFunc ) where -import Day1 +import Day2 someFunc :: IO () -someFunc = day1 +someFunc = day2 diff --git a/test/Day2Spec.hs b/test/Day2Spec.hs new file mode 100644 index 0000000..389cdee --- /dev/null +++ b/test/Day2Spec.hs @@ -0,0 +1,45 @@ +{-# LANGUAGE OverloadedStrings #-} +module Day2Spec (spec) where +import Test.Hspec +import Day2.Shared +import Day2.Part1 +import Day2.Part2 + +input :: String +input = "A Y\nB X\nC Z" + +spec :: Spec +spec = + describe "Day2" $ do + describe "Day2 - Shared" $ do + it "should have scores for shapes" $ do + shapeScore Rock `shouldBe` Score 1 + shapeScore Paper `shouldBe` Score 2 + shapeScore Scissors `shouldBe` Score 3 + it "can sum up scores" $ do + Score 1 <> Score 2 `shouldBe` Score 3 + it "can play games" $ do + play (Game (Rock, Paper)) `shouldBe` shapeScore Paper <> gameWin + describe "Day2 - Part1" $ do + it "can parse game plan" $ do + parseGameList input `shouldBe` games + it "can parse a single game" $ do + readGame "A Y" `shouldBe` Game (Rock, Paper) + readGame "B X" `shouldBe` Game (Paper, Rock) + readGame "C Z" `shouldBe` Game (Scissors, Scissors) + it "can sum up games" $ do + playGames games `shouldBe` Score 15 + it "can play game plan" $ do + day2_1 input `shouldBe` Score 15 + describe "Day2 - Part1" $ do + it "can parse game plan as hints" $ do + readGameHints input `shouldBe` gameHints + it "can convert game plan" $ do + map executePlan gameHints `shouldBe` [Game (Rock, Rock), + Game (Paper, Rock), Game (Scissors, Rock)] + it "can play a game plan" $ do + day2_2 input `shouldBe` Score 12 + where + games = [Game (Rock, Paper), Game (Paper, Rock), Game (Scissors, Scissors)] + gameHints = [GameHint (Rock, Draw), GameHint (Paper, Lose), GameHint (Scissors, Win)] +