|
|
@ -15,38 +15,26 @@ data Shape = Rock | Paper | Scissors
|
|
|
|
data Outcome = Win | Lose | Draw
|
|
|
|
data Outcome = Win | Lose | Draw
|
|
|
|
deriving (Eq)
|
|
|
|
deriving (Eq)
|
|
|
|
|
|
|
|
|
|
|
|
convertToShape :: T.Text -> Shape
|
|
|
|
toShape :: T.Text -> Shape
|
|
|
|
convertToShape x
|
|
|
|
toShape c
|
|
|
|
| x == "A" || x == "X" = Rock
|
|
|
|
| c == "A" || c == "X" = Rock
|
|
|
|
| x == "B" || x == "Y" = Paper
|
|
|
|
| c == "B" || c == "Y" = Paper
|
|
|
|
| x == "C" || x == "Z" = Scissors
|
|
|
|
| c == "C" || c == "Z" = Scissors
|
|
|
|
| otherwise = error $ show x
|
|
|
|
| otherwise = error $ show c
|
|
|
|
|
|
|
|
|
|
|
|
convertToOutcome :: T.Text -> Outcome
|
|
|
|
toOutcome :: T.Text -> Outcome
|
|
|
|
convertToOutcome "X" = Lose
|
|
|
|
toOutcome "X" = Lose
|
|
|
|
convertToOutcome "Y" = Draw
|
|
|
|
toOutcome "Y" = Draw
|
|
|
|
convertToOutcome "Z" = Win
|
|
|
|
toOutcome "Z" = Win
|
|
|
|
|
|
|
|
toOutcome c = error $ show c
|
|
|
|
|
|
|
|
|
|
|
|
parseInput :: T.Text -> [(Shape, T.Text)]
|
|
|
|
pScore :: Shape -> Int
|
|
|
|
parseInput input = map someFunc . T.lines $ input -- ["A Y", "B X"] -> [(Rock, Paper), (Paper, Scissors)]
|
|
|
|
pScore Rock = 1
|
|
|
|
where
|
|
|
|
pScore Paper = 2
|
|
|
|
someFunc :: T.Text -> (Shape, T.Text)
|
|
|
|
pScore Scissors = 3
|
|
|
|
someFunc line = (convertToShape first, second)
|
|
|
|
|
|
|
|
where
|
|
|
|
|
|
|
|
[first, second] = T.words $ line
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
score :: Shape -> Int
|
|
|
|
|
|
|
|
score Rock = 1
|
|
|
|
|
|
|
|
score Paper = 2
|
|
|
|
|
|
|
|
score Scissors = 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
part1 :: [(Shape, T.Text)] -> Int
|
|
|
|
|
|
|
|
part1 input = sum $ map (\(opp, player) -> outcomeScore (opp, player) + score player) input'
|
|
|
|
|
|
|
|
where
|
|
|
|
|
|
|
|
input' = map (B.second convertToShape) input
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
outcomeScore :: (Shape, Shape) -> Int
|
|
|
|
oScore :: (Shape, Shape) -> Int
|
|
|
|
outcomeScore (opp, player)
|
|
|
|
oScore (opp, player)
|
|
|
|
| player == beats opp = 6
|
|
|
|
| player == beats opp = 6
|
|
|
|
| player == loses opp = 0
|
|
|
|
| player == loses opp = 0
|
|
|
|
| otherwise = 3
|
|
|
|
| otherwise = 3
|
|
|
@ -61,15 +49,21 @@ loses Rock = Scissors
|
|
|
|
loses Paper = Rock
|
|
|
|
loses Paper = Rock
|
|
|
|
loses Scissors = Paper
|
|
|
|
loses Scissors = Paper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scores :: [(Shape, Shape)] -> [Int]
|
|
|
|
|
|
|
|
scores = map (\(o, p) -> oScore (o, p) + pScore p)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parseInput :: T.Text -> [(Shape, T.Text)]
|
|
|
|
|
|
|
|
parseInput = map convert . T.lines
|
|
|
|
|
|
|
|
where
|
|
|
|
|
|
|
|
convert line = let [fst, snd] = T.words line in (toShape fst, snd)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
part1 :: [(Shape, T.Text)] -> Int
|
|
|
|
|
|
|
|
part1 input = sum $ scores $ map (B.second toShape) input
|
|
|
|
|
|
|
|
|
|
|
|
part2 :: [(Shape, T.Text)] -> Int
|
|
|
|
part2 :: [(Shape, T.Text)] -> Int
|
|
|
|
part2 input = sum $ map (\(opp, player) -> outcomeScore (opp, player) + score player) shapeList
|
|
|
|
part2 input = sum $ scores $ map tupleToShape outcomes
|
|
|
|
where
|
|
|
|
where
|
|
|
|
outcomeList = map (B.second convertToOutcome) input -- [(Shape, Outcome)]
|
|
|
|
outcomes = map (B.second toOutcome) input
|
|
|
|
shapeList = map outcomeToShape outcomeList
|
|
|
|
tupleToShape (shape, Win) = (shape, beats shape)
|
|
|
|
outcomeToShape (shape, outcome) =
|
|
|
|
tupleToShape (shape, Lose) = (shape, loses shape)
|
|
|
|
let outcome' =
|
|
|
|
tupleToShape (shape, _) = (shape, shape)
|
|
|
|
case outcome of
|
|
|
|
|
|
|
|
Win -> beats shape
|
|
|
|
|
|
|
|
Lose -> loses shape
|
|
|
|
|
|
|
|
Draw -> shape
|
|
|
|
|
|
|
|
in (shape, outcome')
|
|
|
|
|
|
|
|