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 }