Rock Paper Scissors
Tags: adventofcode, algorithms, javascript, programming
Published: 2022-12-02 19:35:07

## [Advent of Code 2022 Day 2](https://adventofcode.com/2022/day/2)

## Part 1
1. It was bound to happen eventually
2. Learning my ABCs and 123s
3. Going from A to Z, so to speak
4. My algorithm in JavaScript

### It was bound to happen eventually
"Want to learn programming?" they say.
"Why not build a simple game?" they say.
"How about Rock Paper Scissors?" they say.

AoC has avoided it seven years. Until now.

How exciting!

### Learning my ABCs and 123s
- A and X and 1 for Rock
- B and Y and 2 for Paper
- C and Z and 3 for Scissors

Opponent's point of view:
- A beats Z
- C beats Y
- B beats X

Player's point of view:
- X beats C
- Y beats A
- Z beats B

And the formula for a round's score:
- Amount above for what player chose, plus...
- 0 for player loss
- 3 for tie
- 6 for player win

### Going from A to Z, so to speak
I need to turn this:
```
A Y
B X
C Z
```

Into this:
```
8
1
6
```

In order to get `15`.

Starting with the first round:
```
A Y
```

I could use a few dictionaries to map winners and amounts:
```js
const elf = { A: 'Z', C: 'Y', B: 'X' }
const player = { X: 'C', Y: 'A', Z: 'B' }
const score = { X: 1, Y: 2, Z: 3 }
```

Three conditions:
```js
if (player[col2] == col1) { 
  // player wins 
} else if (elf[col1] == col2) {
  // elf wins
} else {
  // 'twas a draw
}
```

Would this work on the first round?
```
A Y
player[Y] == 'A' // true
player wins: 6
Y = 2
6 + 2 = 8
Success!
```

Great! Second round?
```
B X
player[X] == 'C' // false
elf[B] == 'X' // true
player loses: 0
X = 1
1 + 0 = 1
Success!
```

Great! Third round?
```
C Z
player[Z] == 'C' // false
elf[C] == 'Z' // false
draw: 3
Z = 3
3 + 3 = 6
Success!
```

It seems this algorithm and data structure will help me solve Part 1!

### My algorithm in JavaScript
```js
const elf = { A: 'Z', C: 'Y', B: 'X' }
const player = { X: 'C', Y: 'A', Z: 'B' }
const score = { X: 1, Y: 2, Z: 3 }
return input
  .split('\n')
  .reduce((total, round) => {
    let [col1, col2] = round.split(' ')
    if (player[col2] == col1) { 
      return total += score[col2] + 6
    } else if (elf[col1] == col2) {
      return total += score[col2]
    } else {
      return total += score[col2] + 3
    }
  }, 0)
```

## Part 2
1. Just what I need
2. My algorithm in JavaScript

### Just what I need
An expectedly clever switch of the rules!
- X needs me to lose
- Y needs me to draw
- Z needs me to win

How will I decide what I play?

I'll reference example round one again:
```
A Y
```

`Y` needs me to draw (pick the same thing as my opponent).

What draw's to an `A`? `X`

How might I represent that - and losing and winning - as a data structure?

```
{
  A: { X: 'Z', Y: 'X', Z: 'Y' },
  B: { X: 'X', Y: 'Y', Z: 'Z' },
  C: { X: 'Y', Y: 'Z', Z: 'X' },
}
```

Here I've mapped the first column to the second column to the player's necessary choice.

Trying round one again:
```
A Y
A: Y: X
Y is a draw = 3
X = 1
3 + 1 = 4
Success!
```

Trying round two:
```
B X
B: X: X
X is a loss = 0
X = 1
0 + 1 = 1
Success!
```

```
C Z
C: Z: X
Z is a win = 6
X = 1
6 + 1 = 7
Success!
```

It seems this algorithm and data structure will help me solve Part 2!

### My algorithm in JavaScript
```js
const move = {
  A: { X: 'Z', Y: 'X', Z: 'Y' },
  B: { X: 'X', Y: 'Y', Z: 'Z' },
  C: { X: 'Y', Y: 'Z', Z: 'X' },
}
const score = { X: 1, Y: 2, Z: 3 }
const outcome = { X: 0, Y: 3, Z: 6 }
return input
  .split('\n')
  .reduce((total, round) => {
    let [col1, col2] = round.split(' ')
    return total += score[move[col1][col2]] + outcome[col2]
  }, 0)
```

## I did it!!
- I solved both parts!
- I worked my way toward solutions by writing what I observed and thought, correcting myself along the way!
- I was surprised that my code for Part 2 is shorter than my code for Part 1! I didn't need all the conditions!

This was my funnest time playing Rock Paper Scissors!