# Advent of Code 2022 - Day 2: Rock Paper Scissors

::

 ```1 2``` ```#lang iracket/lang #:require racket (require "../advent.rkt") ```

## Day 2 - Part 1

Rock, Paper, Scissors

For example, suppose you were given the following strategy guide:

``````A Y
B X
C Z``````

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?

 `1` ```(define in (parse-aoc 2 chars)) ```
``````----------------------------------------------------------------------------------------------------
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:

 ``` 1 2 3 4 5 6 7 8 9 10``` ```(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:

 ```1 2 3 4 5 6 7``` ```(define (shape-score shape) (match shape [ 'rock 1 ] [ 'paper 2 ] [ 'scissors 3 ])) (shape-score 'scissors) ```

`3`

Determine an outcome:

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13``` ```(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:

 ```1 2 3 4 5 6 7``` ```(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:

 ```1 2 3 4 5 6 7 8 9``` ```(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:

 ```1 2 3``` ```(foldl (λ (pair sum) (+ (round pair) sum)) ; function to fold 0 ; initial value in) ; 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:

 ```1 2 3 4 5 6 7``` ```(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:

 ```1 2 3 4 5 6 7 8 9``` ```(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:

 ``` 1 2 3 4 5 6 7 8 9 10``` ```(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`:

 ```1 2 3``` ```(foldl (λ (pair sum) (+ (round pair) sum)) ; function to fold 0 ; initial value in) ; list ```

`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!

 ``` 1 2 3 4 5 6 7 8 9 10 11 12``` ```;; 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`

 ``` 1 2 3 4 5 6 7 8 9 10 11 12``` ```;; 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`