Back to blog

Advent of Code: Day Two

Spoilers for Advent of Code below

Day two is done! Again, as expected this was pretty simple - construct a basic Rock, Paper, Scissors game from an esoteric strategy guide and then calculate the score. Do these elves ever actually work?

The strategy guide looks like this:

A Y
B X
C Z

Column A maps to the other player's move (A -> Rock, B -> Paper, C -> Scissors), while column B maps to your move.

Implementing part one

To begin with, we assume that X, Y, and Z map directly to moves, much in the same way that they do for column A. We then use that to calculate a score. Firstly our move gets given a rating (1 for Rock, 2 for Paper, 3 for Scissors). Then We get a score based on the outcome of the game - a win is 6 points, a loss 0 , and a draw 3.

Pretty simple stuff. I used an enum to represent a move, an a struct for rounds:

pub enum Moves {
    Rock,
    Paper,
    Scissors
} 

#[derive(Debug, PartialEq, Eq)]
pub struct Round {
    pub first: Moves,
    pub second: Moves
}

I then map my columns to moves, using simple match statements:

let their_move = match column_a {
    "A" => Moves::Rock,
    "B" => Moves::Paper,
    "C" => Moves::Scissors
}

let my_move = match column_b {
    "X" => Moves::Rock,
    "Y" => Moves::Paper,
    "Z" => Moves::Scissors
}

Assign a shape score, again using a match:

let shape_score = match shape {
    Moves::Rock => 1,
    Moves::Paper => 2,
    Moves::Scissors => 3,
};

Finally, I just need to actually work out the outcome and return the score for it, add it to the shape score, and return it. I'm using nested matches for this, but there's undoubtedly a better way to handle it.

let game_score = match their_move {
    Moves::Rock => {
        match my_move {
            Moves::Rock => 3, // Draw
            Moves::Paper => 6, // Win
            Moves::Scissors => 0, // Loss
        }
    },
    Moves::Paper => {
        match my_move {
            Moves::Rock => 0,
            Moves::Paper => 3,
            Moves:Scissors => 6
        }
    },
    Moves::Scissors => {
        match my_move {
            Moves::Rock => 6,
            Moves::Paper => 0,
            Moves::Scissors => 3,
        }
    }
}
game_score + shape_score

Aaand it worked - after running it with my output and summing the result, got my first start.

Part two

Part two was much quicker - the only rule change was that instead of directly translating to a move, the second column indicated the expected outcome of the match: X meant I had to lose, Y a draw, and Z a win. That was easy enough to do, I had to change the logic for when I map my_move from a str:

let my_move = match column_b {
    "X" => match their_move {
        Moves::Rock => Moves::Scissors,
        Moves::Paper => Moves::Rock,
        Moves::Scissors => Moves::Paper
    }
    "Y" => first,
    "Z" => match first {
        Moves::Rock => Moves::Paper,
        Moves::Paper => Moves::Scissors,
        Moves::Scissors => Moves::Rock
    },
    _ => Moves::Rock
};

The rest of the logic stays the same, so no changes needed.