From 6d72191e2ce5d423ca03c894d2dad1d3061bd4f3 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:27:29 +0200 Subject: Refile for merging repos --- 2021/src/bin/day_6.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 2021/src/bin/day_6.rs (limited to '2021/src/bin/day_6.rs') diff --git a/2021/src/bin/day_6.rs b/2021/src/bin/day_6.rs new file mode 100644 index 0000000..9a40f9e --- /dev/null +++ b/2021/src/bin/day_6.rs @@ -0,0 +1,79 @@ +use nom::{ + bytes::complete::tag, + character::complete::u32 as nom_u32, + combinator::{map, map_res}, + multi::separated_list1, + IResult, ToUsize, +}; +use std::{collections::VecDeque, fs}; +use thiserror::Error; + +fn main() -> Result<(), Box> { + let input = fs::read_to_string("inputs/day_6.txt")?; + let mut swarm = parse_swarm(&input).unwrap().1; + for _ in 0..80 { + swarm.grow(); + } + dbg!(swarm.fish_sum()); + + for _ in 80..256 { + swarm.grow(); + } + dbg!(swarm.fish_sum()); + + Ok(()) +} + +#[derive( + Default, Debug, Clone, Copy, derive_more::Add, derive_more::AddAssign, derive_more::Sum, +)] +struct FishCount(u64); + +const FISH_INITIAL_SPAWN_COUNTDOWN: usize = 9; +const FISH_REPEAT_SPAWN_COUNTDOWN: usize = 7; +#[derive(Debug)] +struct Swarm { + fish: VecDeque, +} + +#[derive(Debug, Error)] +enum SwarmParseError { + #[error("input was out of range")] + OutOfRange, +} + +impl Swarm { + fn new(fish_counters: Vec) -> Result { + let mut fish = VecDeque::with_capacity(FISH_INITIAL_SPAWN_COUNTDOWN); + for _ in 0..FISH_INITIAL_SPAWN_COUNTDOWN { + fish.push_back(FishCount::default()); + } + for fish_counter in fish_counters { + if fish_counter > fish.len() { + return Err(SwarmParseError::OutOfRange); + } + fish[fish_counter] += FishCount(1); + } + Ok(Swarm { fish }) + } + + fn grow(&mut self) { + let spawning = self + .fish + .pop_front() + .expect("Fish buffer should maintain exactly 9 entries"); + self.fish[FISH_REPEAT_SPAWN_COUNTDOWN - 1] += spawning; + self.fish.push_back(spawning); + } + + fn fish_sum(&self) -> FishCount { + self.fish.iter().copied().sum() + } +} + +fn parse_swarm(input: &str) -> IResult<&str, Swarm> { + map_res( + separated_list1(tag(","), map(nom_u32, |n| n.to_usize())), + Swarm::new, + )(input) +} -- cgit v1.2.3