Advent of Code 2022-Day 2: Rock Paper Scissors
Day 2 - Part 1
Rock, Paper, Scissors
For example, suppose you were given the following strategy guide:
We're told that A=Rock, B=Paper and C=Scissors, and it's proposed that X=Rock, Y=Paper and Z=Scissors.
We're also told the score is computed as follows: add the score of the shape (1 for Rock, 2 for Paper and 3 for Scissors) to the outcome (0 if we lost, 3 if a draw and 6 if we won).
What would your total score be if everything goes exactly according to your strategy guide?
----------------------------------------------------------------------------------------------------
day02.txt -> 10000 chars, 2500 lines; first 3 lines; last 2 lines:
----------------------------------------------------------------------------------------------------
B Z
C Z
B X
...
C Y
B Z
----------------------------------------------------------------------------------------------------
(parse 2) -> 2500 entries:
----------------------------------------------------------------------------------------------------
((#\B #\Z)
(#\C #\Z)
...
(#\B #\Z))
----------------------------------------------------------------------------------------------------
Parsing gives us a list of pairs of plays e.g. player 1 plays A=Rock, player 2 plays Y=Paper, etc. Let's define a function that maps a letter to a shape:
(define (char->shape c)
(match c
[ #\A 'rock ]
[ #\X 'rock ]
[ #\B 'paper ]
[ #\Y 'paper ]
[ #\C 'scissors ]
[ #\Z 'scissors ]))
(char->shape #\Y)
'paper
Determine the score of a shape:
(define (shape-score shape)
(match shape
[ 'rock 1 ]
[ 'paper 2 ]
[ 'scissors 3 ]))
(shape-score 'scissors)
3
Determine an outcome:
(define (outcome us them)
(match (cons us them)
[ '(rock . scissors) 'win ]
[ '(rock . rock) 'draw ]
[ '(rock . paper) 'loss ]
[ '(paper . rock) 'win ]
[ '(paper . paper) 'draw ]
[ '(paper . scissors) 'loss ]
[ '(scissors . paper) 'win ]
[ '(scissors . scissors) 'draw ]
[ '(scissors . rock) 'loss ]))
(outcome 'paper 'rock)
'win
Determine the score of an outcome:
(define (outcome-score outcome)
(match outcome
[ 'loss 0 ]
[ 'draw 3 ]
[ 'win 6 ]))
(outcome-score 'win)
6
Let's create a round function that accepts a list of characters from the input, e.g. (them us), and computes the score, given the outcome:
(define (round pair)
(let ([ them (char->shape (first pair)) ]
[ us (char->shape (second pair)) ])
(+ (shape-score us)
(outcome-score (outcome us them)))))
(list (round '(#\A #\Y))
(round '(#\B #\X))
(round '(#\C #\Z)))
'(8 1 6)
The hard part is done, now all we have to do is fold the + and round functions over the list:
12458
Part 2
The Elf finishes helping with the tent and sneaks back over to you. "Anyway, the second column says how the round needs to end: X means you need to lose, Y means you need to end the round in a draw, and Z means you need to win. Good luck!"
Ok, it looks like we'll need a function to map the second column to an expected outcome:
(define (expected-outcome c)
(match c
[ #\X 'loss ]
[ #\Y 'draw ]
[ #\Z 'win ]))
(expected-outcome #\Y)
'draw
And, we'll need a function that returns a shape for us to play given the other player's shape and the expected outcome. Since we already have a function to return an outcome given both players' choices, we'll just look through the list of 3 shapes to find the right one:
(define (expected-shape pair)
(let ([ shapes (map char->shape '(#\A #\B #\C)) ]
[ them (char->shape (first pair)) ]
[ desired (expected-outcome (second pair)) ])
(findf (λ (shape)
(eq? desired (outcome shape them)))
shapes)))
(expected-shape '(#\A #\Y))
'rock
We'll redefine the round function with the new information from part 2:
(define (round pair)
(let ([ outcome (expected-outcome (second pair)) ]
[ them (char->shape (first pair)) ]
[ us (expected-shape pair) ])
(+ (shape-score us)
(outcome-score outcome))))
(list (round '(#\A #\Y))
(round '(#\B #\X))
(round '(#\C #\Z)))
'(4 1 7)
The fold for part 2 is identical, given the new round:
12683
A much simpler solution
Todd Ginsberg used a much simpler solution, and it was a good reminder for me to look for similar opportunities in the future days!
;; Part 1
(for/sum ([ pair in ])
(match pair
[ '(#\A #\X) 4 ]
[ '(#\A #\Y) 8 ]
[ '(#\A #\Z) 3 ]
[ '(#\B #\X) 1 ]
[ '(#\B #\Y) 5 ]
[ '(#\B #\Z) 9 ]
[ '(#\C #\X) 7 ]
[ '(#\C #\Y) 2 ]
[ '(#\C #\Z) 6 ]))
12458
;; Part 2
(for/sum ([ pair in ])
(match pair
[ '(#\A #\X) 3 ]
[ '(#\A #\Y) 4 ]
[ '(#\A #\Z) 8 ]
[ '(#\B #\X) 1 ]
[ '(#\B #\Y) 5 ]
[ '(#\B #\Z) 9 ]
[ '(#\C #\X) 2 ]
[ '(#\C #\Y) 6 ]
[ '(#\C #\Z) 7 ]))
12683