56 lines
1.4 KiB
Rust
56 lines
1.4 KiB
Rust
use std::{
|
|
fs::File,
|
|
io::{BufRead, BufReader},
|
|
};
|
|
|
|
fn main() -> () {
|
|
let path = "input.txt";
|
|
|
|
let input = File::open(path).unwrap();
|
|
let buf = BufReader::new(input);
|
|
|
|
let score: i32 = buf
|
|
.lines()
|
|
.map(|line| {
|
|
let line = line.unwrap();
|
|
let opponent: i32 = match &line[0..1] {
|
|
"A" => 0,
|
|
"B" => 1,
|
|
"C" => 2,
|
|
_ => panic!("Invalid input"),
|
|
};
|
|
let you: i32 = match &line[2..3] {
|
|
"X" => 0,
|
|
"Y" => 1,
|
|
"Z" => 2,
|
|
_ => panic!("Invalid input"),
|
|
};
|
|
pick_score(you) + win_score(opponent, you)
|
|
})
|
|
.sum();
|
|
|
|
println!("{}", score);
|
|
}
|
|
|
|
/// Transforms the "wrapping" cases of RPS into the trivial "middle" case where A wins if A > B
|
|
fn normalise_mod3(opponent: i32, you: i32) -> (i32, i32) {
|
|
let i = match opponent {
|
|
0 => 1,
|
|
2 => 2,
|
|
_ => 0,
|
|
};
|
|
((opponent + i) % 3, (you + i) % 3)
|
|
}
|
|
|
|
/// Get score component for losing (0 points), drawing (3 points) or winning (6 points) the round
|
|
fn win_score(opponent: i32, you: i32) -> i32 {
|
|
let (opponent, you) = normalise_mod3(opponent, you);
|
|
let is_won = you - opponent.signum() + 1; // 0 on loss, 1 on draw, 2 on win}
|
|
3 * is_won
|
|
}
|
|
|
|
/// Get score component for your pick (trivial)
|
|
fn pick_score(you: i32) -> i32 {
|
|
you + 1
|
|
}
|