// Accumulator structure... // parse each line use simple_error::{SimpleError,bail}; #[derive(PartialEq)] enum Move{ Rock, Paper, Scissors } enum Res { Win, Draw, Loss } fn parse_m1(c: char) -> Result { match c { 'A' => Ok(Move::Rock), 'B' => Ok(Move::Paper), 'C' => Ok(Move::Scissors), _ => bail!("invalid character {}", c) } } // fn parse_m2(c: char) -> Result { // match c { // 'X' => Ok(Move::Rock), // 'Y' => Ok(Move::Paper), // 'Z' => Ok(Move::Scissors), // _ => bail!("invalid character {}", c) // } // } fn parse_req_res(c: char) -> Result { match c { 'X' => Ok(Res::Loss), 'Y' => Ok(Res::Draw), 'Z' => Ok(Res::Win), _ => bail!("invalid character {}", c) } } // fn win(opp: Move, you: Move) -> Res { // match opp { // Move::Rock => match you { // Move::Rock => Res::Draw, // Move::Paper => Res::Win, // Move::Scissors => Res::Loss, // }, // Move::Paper => match you { // Move::Rock => Res::Loss, // Move::Paper => Res::Draw, // Move::Scissors => Res::Win, // }, // Move::Scissors => match you { // Move::Rock => Res::Win, // Move::Paper => Res::Loss, // Move::Scissors => Res::Draw, // } // } // } fn calc_req_move(opp: Move, req_res: Res) -> Move { match req_res { Res::Win => match opp { Move::Rock => Move::Paper, Move::Paper => Move::Scissors, Move::Scissors => Move::Rock } Res::Draw => opp, Res::Loss => match opp { Move::Rock => Move::Scissors, Move::Paper => Move::Rock, Move::Scissors => Move::Paper } } } // fn score(opp: Move, you: Move) -> u32 { // let ms: u32 = match you { // Move::Rock => 1, // Move::Paper => 2, // Move::Scissors => 3, // }; // let ws: u32 = match win(opp, you) { // Res::Win => 6, // Res::Draw => 3, // Res::Loss => 0, // }; // return ms+ws; // } fn score(opp: Move, req_res: Res) -> u32 { let ws: u32 = match req_res { Res::Win => 6, Res::Draw => 3, Res::Loss => 0, }; let mm = calc_req_move(opp, req_res); let ms: u32 = match mm { Move::Rock => 1, Move::Paper => 2, Move::Scissors => 3, }; return ms+ws; } // fn parse_turn(line: &str) -> Result<(Move, Move), SimpleError> { // let mut lc = line.chars(); // let e1: SimpleError = SimpleError::new("not enough characters in input!"); // let c1 = lc.next().ok_or(e1.clone())?; // lc.next().ok_or(e1.clone())?; // let c2 = lc.next().ok_or(e1.clone())?; // let m_opp = parse_m1(c1)?; // let m_you = parse_m2(c2)?; // Ok((m_opp, m_you)) // } fn parse_turn(line: &str) -> Result<(Move, Res), SimpleError> { let mut lc = line.chars(); let e1: SimpleError = SimpleError::new("not enough characters in input!"); let c1 = lc.next().ok_or(e1.clone())?; lc.next().ok_or(e1.clone())?; let c2 = lc.next().ok_or(e1.clone())?; let m_opp = parse_m1(c1)?; let req_res = parse_req_res(c2)?; Ok((m_opp, req_res)) } pub fn run(input: String) { let score: u32 = input.lines().map(|line| { let (m_opp, m_you) = parse_turn(line).expect("invalid input line!"); score(m_opp, m_you) }).sum::(); println!("day 2: {}", score); }