76 lines
1.9 KiB
Rust
76 lines
1.9 KiB
Rust
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
|
|
);
|
|
}
|
|
}
|