Skip to content

Commit 646874c

Browse files
docs(day2): comment day2 explicitly for non-haskell folks
1 parent 7fe09ce commit 646874c

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

solutions/Days/Day02.hs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,73 @@
11
module Days.Day02 (day02) where
22

33
import AOC (Solution (..))
4-
import Control.Arrow ((>>>), (***), second)
4+
import Control.Arrow ((<<<), (***), second)
55
import Data.Maybe (fromMaybe)
66
import qualified Data.Text as T
77

88
day02 :: Solution
99
day02 = Solution parseInput part1 part2
1010

11+
-- | an RPS move
1112
data RPS = Rock | Paper | Scissors
1213
deriving (Show, Eq, Enum, Bounded)
1314

14-
data Action = Lose | Draw | Win
15+
-- | a game outcome
16+
data Outcome = Lose | Draw | Win
1517
deriving (Show, Eq)
1618

19+
-- | Parse the input into tuples consisting of (RPS move, "XYZ" Char).
1720
parseInput :: T.Text -> [(RPS, T.Text)]
18-
parseInput = fmap (T.breakOn " " >>> translate table *** T.tail) . T.lines
21+
parseInput = fmap (lookup' table *** T.tail <<< T.breakOn " ") . T.lines
1922
where
2023
table = [("A", Rock), ("B", Paper), ("C", Scissors)]
2124

25+
-- | Part 1, translate the "XYZ" chars into RPS moves, score the
26+
-- results, sum them together.
2227
part1 :: [(RPS, T.Text)] -> Int
23-
part1 = sum . fmap (score . second (translate table))
28+
part1 = sum . fmap (score . second (lookup' table))
2429
where
2530
table = [("X", Rock), ("Y", Paper), ("Z", Scissors)]
2631

32+
-- | Part 2, translate the "XYZ" chars into game outcome Actions,
33+
-- match those actions with the necessary RPS move to achieve the
34+
-- desired action, score the results, and sum them together.
2735
part2 :: [(RPS, T.Text)] -> Int
28-
part2 = sum . fmap (score . matchAction . second (translate table))
36+
part2 = sum . fmap (score . matchAction . second (lookup' table))
2937
where
3038
table = [("X", Lose), ("Y", Draw), ("Z", Win)]
3139

32-
translate :: (Show a, Eq a) => [(a, b)] -> a -> b
33-
translate table ch =
34-
fromMaybe (error $ "Lookup failed: " ++ show ch) $ lookup ch table
40+
-- | Wrapper around 'lookup' that 'error's out if the lookup fails.
41+
lookup' :: (Show a, Eq a) => [(a, b)] -> a -> b
42+
lookup' table a =
43+
fromMaybe (error $ "Lookup failed: " ++ show a) $ lookup a table
3544

36-
matchAction :: (RPS, Action) -> (RPS, RPS)
45+
-- | Translate a desired 'Outcome' into an 'RPS' move based on the
46+
-- 'RPS' move given for player 1 in the first tuple position.
47+
matchAction :: (RPS, Outcome) -> (RPS, RPS)
3748
matchAction (rps, action) = (rps, match)
3849
where
3950
match = case action of
4051
Lose -> prevRPS rps
4152
Draw -> rps
4253
Win -> nextRPS rps
4354

55+
-- | Score an RPS round. Uses the derived 'Enum' instance for 'RPS' to
56+
-- determine a moves individual value.
4457
score :: (RPS, RPS) -> Int
4558
score (a, b) = (fromEnum b + 1) + beats a b
4659

60+
-- | Determine the points received by player 2 when facing player 1's
61+
-- move.
4762
beats :: RPS -> RPS -> Int
48-
beats a b
49-
| nextRPS a == b = 6
50-
| a == b = 3
63+
beats p1 p2
64+
| nextRPS p1 == p2 = 6
65+
| p1 == p2 = 3
5166
| otherwise = 0
5267

68+
-- | Bounded successor/predecessor for 'RPS' with wrap-around at both
69+
-- upper and lower bounds. Uses 'RPS's derived 'Enum' and 'Bounded'
70+
-- instances.
5371
nextRPS, prevRPS :: RPS -> RPS
5472
nextRPS rps
5573
| rps == maxBound = minBound

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy