use std::collections::HashMap; use std::{ fs::File, io::{prelude::*, BufReader}, path::Path, }; fn lines_from_file(filename: impl AsRef) -> Vec { let file = File::open(filename).expect("no such file"); let buf = BufReader::new(file); buf.lines() .map(|l| l.expect("Could not parse line")) .collect() } // --- #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] enum Move { Rock, Paper, Scissors, INVALID, Win, Lose, Tie, } fn main() { let lines = lines_from_file("../full/day02.txt"); part1(&lines); part2(&lines); } fn to_enum(s: &str, part: i32) -> Move { if s == "A" { return Move::Rock; } else if s == "B" { return Move::Paper; } else if s == "C" { return Move::Scissors; } else if s == "X" { if part == 1 { return Move::Rock; } else { return Move::Lose; } } else if s == "Y" { if part == 1 { return Move::Paper; } else { return Move::Tie; } } else if s == "Z" { if part == 1 { return Move::Scissors; } else { return Move::Win; } } return Move::INVALID; } fn parse(lines: &Vec, part: i32) -> (Vec, Vec) { let mut oppt: Vec = Vec::new(); let mut mine: Vec = Vec::new(); for line in lines { let split = line.split_whitespace().collect::>(); oppt.push(to_enum(split[0], part)); mine.push(to_enum(split[1], part)); } return (oppt, mine); } fn score_1(o: &Move, m: Move) -> i32 { let mut score: i32 = 0; let scores: HashMap = HashMap::from([ (Move::Rock, 1), (Move::Paper, 2), (Move::Scissors, 3), (Move::Win, 6), (Move::Tie, 3), (Move::Lose, 0), ]); // For my choice score += scores[&m]; // for which outcome if o == &m { //println!("Tie"); score += scores[&Move::Tie]; } else if (m == Move::Paper && o == &Move::Rock) || (m == Move::Rock && o == &Move::Scissors) || (m == Move::Scissors && o == &Move::Paper) { //println!("Win"); score += scores[&Move::Win]; } else { //println!("Lose"); score += scores[&Move::Lose]; } return score; } fn part1(lines: &Vec) { let (oppt, mine) = parse(lines, 1); let mut score: i32 = 0; for (idx, el) in oppt.iter().enumerate() { score += score_1(el, mine[idx]); } println!("{}", score); } fn score_2(o: &Move, m: Move) -> i32 { let mut new_move: &Move = &Move::INVALID; let mut score: i32 = 0; let scores: HashMap = HashMap::from([ (Move::Rock, 1), (Move::Paper, 2), (Move::Scissors, 3), (Move::Win, 6), (Move::Tie, 3), (Move::Lose, 0), ]); // For my choice if m == Move::Tie { new_move = o; } else if m == Move::Lose { if o == &Move::Rock { new_move = &Move::Scissors; } else if o == &Move::Paper { new_move = &Move::Rock; } else { new_move = &Move::Paper; } } else if m == Move::Win { if o == &Move::Rock { new_move = &Move::Paper; } else if o == &Move::Paper { new_move = &Move::Scissors; } else { new_move = &Move::Rock; } } score += scores[new_move]; score += scores[&m]; return score; } fn part2(lines: &Vec) { let (oppt, mine) = parse(lines, 2); let mut score: i32 = 0; for (idx, el) in oppt.iter().enumerate() { score += score_2(el, mine[idx]); } println!("{}", score); }