use std::fs; use std::io::{self, BufRead}; #[derive(Debug, PartialEq, Clone)] enum Hand { Rock, Paper, Scissors, } fn translate(play: &str) -> Hand { match play { "A" | "X" => Hand::Rock, "B" | "Y" => Hand::Paper, "C" | "Z" => Hand::Scissors, &_ => panic!(), } } fn weight(play: Hand) -> u32 { match play { Hand::Rock => 1, Hand::Paper => 2, Hand::Scissors => 3, } } enum Conclusion { Loose, Draw, Win, } fn strategy(play: &str) -> Conclusion { match play { "X" => Conclusion::Loose, "Y" => Conclusion::Draw, "Z" => Conclusion::Win, &_ => panic!("Invalid input"), } } fn wins(play: Hand) -> Hand { match play { Hand::Rock => Hand::Scissors, Hand::Scissors => Hand::Paper, Hand::Paper => Hand::Rock, } } fn looses(play: Hand) -> Hand { match play { Hand::Scissors => Hand::Rock, Hand::Paper => Hand::Scissors, Hand::Rock => Hand::Paper, } } fn pick_move(strategy: Conclusion, other: Hand) -> Hand { match strategy { Conclusion::Draw => other, Conclusion::Win => looses(other), Conclusion::Loose => wins(other), } } fn fight(my: Hand, other: Hand) -> u32 { match (my, other) { (a, b) if a == b => 3, (a, b) => { if wins(a) == b { 6 } else { 0 } } } } fn fixed_plays(my: &str, _oponent: Hand) -> Hand { translate(my) } fn reactive_plays(my: &str, oponent: Hand) -> Hand { pick_move(strategy(my), oponent) } fn solver(strategy: &dyn Fn(&str, Hand) -> Hand) -> u32 { let file = fs::File::open("input").unwrap(); let lines = io::BufReader::new(file).lines(); lines.fold(0, |acc, line| { if let [ot, my] = line.unwrap().split_whitespace().collect::>()[..] { let opo = translate(ot); let my_hand = strategy(my, opo.clone()); acc + fight(my_hand.clone(), opo) + weight(my_hand) } else { panic!("Wrong line") } }) } // Super simple strategies fn fixed_plays2(line: &str) -> u32 { match line { "A X" => 3 + 1, // draw rock "A Y" => 6 + 2, // win paper "A Z" => 0 + 3, // loose scissors "B X" => 0 + 1, // loose rock "B Y" => 3 + 2, // draw paper "B Z" => 6 + 3, // win scissors "C X" => 6 + 1, // win rock "C Y" => 0 + 2, // loose paper "C Z" => 3 + 3, // draw scissors &_ => panic!("Invalid play"), } } fn reactive_plays2(line: &str) -> u32 { match line { "A X" => 0 + 3, // loose scissors "A Y" => 3 + 1, // draw paper "A Z" => 6 + 2, // win "B X" => 0 + 1, // loose "B Y" => 3 + 2, // draw "B Z" => 6 + 3, // win "C X" => 0 + 2, // loose "C Y" => 3 + 3, // draw "C Z" => 6 + 1, // win &_ => panic!("Invalid play"), } } fn solver2(strategy: &dyn Fn(&str) -> u32) -> u32 { let file = fs::File::open("input").unwrap(); io::BufReader::new(file) .lines() .map(|x| strategy(&x.unwrap())) .sum() } fn main() { assert_eq!(12535, solver(&fixed_plays)); assert_eq!(15457, solver(&reactive_plays)); assert_eq!(12535, solver2(&fixed_plays2)); assert_eq!(15457, solver2(&reactive_plays2)); println!("All test passed.") }