2022 AoC Day 2 – Rock Paper Scissors

This is a solution to Advent of Code 2022 day 2, written in Raku and Rust.

https://adventofcode.com/2022/day/2

Part One

What would your total score be if everything goes exactly according to your strategy guide?

Each line of the input text has a char A|B|C for the Elf's shape and a char X|Y|Z for your shape. Convert these to values 1|2|3 so they can be compared and summed:

  • A win is shape value + 6
  • A draw is shape value + 3
  • A loss is shape value
say [+] '2-input.txt'.IO.lines.map({
    my ($a, $b) = .trans('ABCXYZ' => '123123').split(' ');
    if $a == $b {
        $b + 3
    } elsif $a+1 == $b || $a == $b+2 {
        $b + 6
    } else {
        $b
    }
});
11386

Rust

use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;

fn main() -> Result<(), Box<dyn Error>> {
    let values = HashMap::from([("A", 1), ("B", 2), ("C", 3), ("X", 1), ("Y", 2), ("Z", 3)]);

    let total = BufReader::new(File::open(
        "/Users/donaldh/git/advent-of-code/2022/2-input.txt",
    )?)
    .lines()
    .map(|x| {
        let pair: Vec<&i32> = x
            .unwrap()
            .split(" ")
            .map(|y| values.get(y).unwrap())
            .collect();
        let first = *pair[0];
        let second = *pair[1];
        if first == second {
            second + 3
        } else if first + 1 == second || first == second + 2 {
            second + 6
        } else {
            second
        }
    })
    .sum::<i32>();

    println!("{:#?}", total);

    Ok(())
}
11386

Part Two

Following the Elf's instructions for the second column, what would your total score be if everything goes exactly according to your strategy guide?

In part two, the second column of input now tells us whether we should lose, draw or win. We need to choose the required shape based on the shape the Elf chooses.

say [+] '2-input.txt'.IO.lines.map({
    my ($a, $s) = .split(' ');

    $a .= trans('ABC' => '123');
    my $b = do given $s {
        when 'X' { $a.trans('123' => '312') }
        when 'Y' { $a }
        when 'Z' { $a.trans('123' => '231') }
    }

    if $a == $b {
        $b += 3
    } elsif $a+1 == $b || $a == $b+2 {
        $b += 6
    } else {
        $b
    }
});
13600

Rust

use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;

fn main() -> Result<(), Box<dyn Error>> {
    let values = HashMap::from([("A", 1), ("B", 2), ("C", 3), ("X", 1), ("Y", 2), ("Z", 3)]);

    let total = BufReader::new(File::open(
        "/Users/donaldh/git/advent-of-code/2022/2-input.txt",
    )?)
    .lines()
    .map(|x| {
        let pair: Vec<&i32> = x
            .unwrap()
            .split(" ")
            .map(|y| values.get(y).unwrap())
            .collect();
        let first = *pair[0];
        let strategy = *pair[1];
        let second = match strategy {
            1 => ((first + 1) % 3) + 1,
            2 => first,
            3 => ((first + 3) % 3) + 1,
            _ => 0,
        };
        if first == second {
            second + 3
        } else if first + 1 == second || first == second + 2 {
            second + 6
        } else {
            second
        }
    })
    .sum::<i32>();

    println!("{:#?}", total);

    Ok(())
}
13600
raku