//! Day 06 of 2021. use crate::prelude::*; /// Shorthand for a [`HashMap`] using [`isize`]s. type FishMap = HashMap; /// Get the solution for day 06 of 2021. pub fn solution() -> Solution { Solution::new(Day::new(6, 2021), part_1, part_2) .with_expected(343441, 1569108373832_i64) } /// The logic to solve part one. fn part_1(input: &str) -> Result { let mut fishes = parse_fishes(input)?; for _ in 0..80 { fishes = simulate_fishes(fishes); } Ok(count_fishes(fishes).to_string()) } /// The logic to solve part two. fn part_2(input: &str) -> Result { let mut fishes = parse_fishes(input)?; for _ in 0..256 { fishes = simulate_fishes(fishes); } Ok(count_fishes(fishes).to_string()) } /// Parse the [`FishMap`]s from the puzzle input. fn parse_fishes(input: &str) -> Result { let mut fishes = FishMap::new(); let individual_fishes = input .split(',') .map(str::parse) .collect::, _>>()?; for fish in individual_fishes { let amount = fishes.entry(fish).or_default(); *amount += 1; } Ok(fishes) } /// Get the sum of the [`FishMap`] values. fn count_fishes(fishes: FishMap) -> isize { fishes.values().sum() } /// Simulate the fishes according to the puzzle's instructions. fn simulate_fishes(fishes: FishMap) -> FishMap { let mut new_fishes = HashMap::new(); for (mut timer, amount) in fishes { timer -= 1; if timer < 0 { let new_fish = new_fishes.entry(8).or_default(); *new_fish += amount; let reset_fish = new_fishes.entry(6).or_default(); *reset_fish += amount; } else { let current_fish = new_fishes.entry(timer).or_default(); *current_fish += amount; } } new_fishes }