use crate::tile::{Operator, Tile}; /// Calculate the score for a given list of tiles. pub fn calc_score(tiles: &[Tile]) -> u32 { tiles .split(|tile| matches!(tile, Tile::Equals)) .map(calc_expression_score) .sum() } fn calc_expression_score(tiles: &[Tile]) -> u32 { let mut digit_score = 0u32; let mut multiplier = 1u32; for token in tiles { match token { Tile::Digit(_) => digit_score += 1, Tile::Operator(Operator::Add | Operator::Subtract) => multiplier = 2, Tile::Operator(Operator::Multiply) => multiplier = 3, Tile::Operator(Operator::Divide) => digit_score += 10, Tile::Equals => unreachable!(), } } digit_score * multiplier } #[cfg(test)] mod tests { use crate::tile::Digit; use super::*; #[test] fn only_digits() { assert_eq!( calc_score(&[ Tile::Digit(Digit::new(7)), Tile::Digit(Digit::new(8)), Tile::Equals, Tile::Digit(Digit::new(9)), Tile::Digit(Digit::new(4)), ]), 4 ); } #[test] fn calc_individually() { assert_eq!( calc_score(&[ Tile::Digit(Digit::new(4)), Tile::Operator(Operator::Add), Tile::Digit(Digit::new(5)), Tile::Equals, Tile::Digit(Digit::new(3)), Tile::Operator(Operator::Multiply), Tile::Digit(Digit::new(3)), ]), 10 ); } #[test] fn diviser_add_to_original_sum() { assert_eq!( calc_score(&[ Tile::Digit(Digit::new(8)), Tile::Operator(Operator::Divide), Tile::Digit(Digit::new(4)), Tile::Equals, Tile::Digit(Digit::new(2)), ]), 13 ); } }