Advent of Code (in MiniScript), Day 2
Tags: miniscript, adventofcode, programming
Published: 2022-12-03 20:19:34

I'm tackling the second [Advent of Code](https://adventofcode.com/) problem.  [This one](https://adventofcode.com/2022/day/2) has complicated directions related to playing a Rock-Paper-Scissors (RPS) game.

In Part A, it all boils down to calculating your total score, where your points for each round depend on the second column of the file as well as whether that represents a RPS win or loss. After thinking about this a moment, I decided to go with a simple approach of simply storing the points each of the nine possible input lines.  

In the `score` map below, I assign a small sum to each combination: the first number in each sum is your points for winning or losing, and the second number is the extra points based on solely on which response (rock, paper, or scissors) the second column represents.  Written out this way, it's easy to see that all the X responses are worth 1, the Y responses are worth 2, and the Z responses are worth 3; and then the 0, 3, and 6 parts rotate around to represent what beats what.

```
score = {}
score.AX = 3 + 1; score.AY = 6 + 2; score.AZ = 0 + 3
score.BX = 0 + 1; score.BY = 3 + 2; score.BZ = 6 + 3
score.CX = 6 + 1; score.CY = 0 + 2; score.CZ = 3 + 3

f = file.open("day2-input.txt")
total = 0
while true
	line = f.readLine
	if line == null then break // end of file
	points = score[line.replace(" ", "")]
	total = total + points
	print line + ": " + points + ", total=" + total
end while
```

The only "trick" here is `score[line.replace(" ", "")]`.  This takes the line read from the file, and replaces the space (in an input like "A X") with an empty string, giving "AX".  We then use this to index into the `score` map, using square-bracket syntax.  Recall that `score["AX"]` is equivalent to `score.AX`, and you'll see how this relates to the values defined at the top of the program.

When run, this prints out each line of the input file, along with the points for that line and the growing total.  The last total printed is the Part A answer, which for me was 11767.

On to Part B!  This one sounds like a complicated wrinkle: based on the second column, you should lose (X), tie (Y), or win (Z) the round, and score it accordingly.  But the way we have our `score` map written out, it's actually pretty easy to update it to the new rules.

```
score = {}
score.AX = 0 + 3; score.AY = 3 + 1; score.AZ = 6 + 2
score.BX = 0 + 1; score.BY = 3 + 2; score.BZ = 6 + 3
score.CX = 0 + 2; score.CY = 3 + 3; score.CZ = 6 + 1

f = file.open("day2-input.txt")
total = 0
while true
	line = f.readLine
	if line == null then break // end of file
	points = score[line.replace(" ", "")]
	total = total + points
	print line + ": " + points + ", total=" + total
end while
```

Now all the X responses lose (0 points), all the Y responses tie (3 points) and all the Z responses win (6 points).  And to this, we add 1, 2, or 3 points representing the bonus for whichever response would lose/tie/win in each situation.  The rest of the program is unchanged.

Running this gave me a different total of 13886, which again was the right answer.

So!  That's day 2 squared away.  I bet a lot of participants wrote some pretty complicated code to figure out what the right response was for each input, calculate the win/loss and  response value in each case, and add it all up within the loop.  The long and complex problem description was certainly trying to lead you in this direction!  But as soon as you note that there are only nine possible inputs, that's a clue that a very simple solution is possible.