2021: day06: refacto

This commit is contained in:
Antoine Martin 2021-12-06 11:34:54 +01:00
parent 7cffb7cdc6
commit bb9265657b

View file

@ -5,7 +5,7 @@ use anyhow::Result;
const INPUT: &str = include_str!("../input/day06.txt"); const INPUT: &str = include_str!("../input/day06.txt");
const SPAWNING_DELAY: u8 = 7; const SPAWNING_DELAY: usize = 7;
const TURNS_PART_1: usize = 80; const TURNS_PART_1: usize = 80;
const TURNS_PART_2: usize = 256; const TURNS_PART_2: usize = 256;
@ -19,63 +19,15 @@ pub fn run() -> Result<String> {
} }
fn part1(input: &str) -> Result<usize> { fn part1(input: &str) -> Result<usize> {
let mut school = input let mut school = input.trim().parse::<School>()?;
.trim()
.split(',')
.map(str::parse::<LanternFish>)
.collect::<Result<Vec<_>>>()?;
for _ in 0..TURNS_PART_1 { Ok(school.grow_for(TURNS_PART_1))
let mut newly_spawned = 0;
for fish in &mut school {
if fish.next_turn() {
newly_spawned += 1;
}
}
school.resize_with(school.len() + newly_spawned, LanternFish::default)
}
Ok(school.len())
} }
fn part2(input: &str) -> Result<usize> { fn part2(input: &str) -> Result<usize> {
let mut school = input.trim().parse::<School>()?; let mut school = input.trim().parse::<School>()?;
for _ in 0..TURNS_PART_2 { Ok(school.grow_for(TURNS_PART_2))
school.next_turn();
}
Ok(school.size())
}
struct LanternFish {
timer: u8,
}
impl LanternFish {
fn spawn() -> Self {
LanternFish {
timer: SPAWNING_DELAY + 1,
}
}
fn next_turn(&mut self) -> bool {
if self.timer == 0 {
self.timer = SPAWNING_DELAY - 1;
true
} else {
self.timer -= 1;
false
}
}
}
impl Default for LanternFish {
fn default() -> Self {
Self::spawn()
}
} }
struct School { struct School {
@ -90,38 +42,37 @@ impl School {
self.fish_timers[i - 1] = self.fish_timers[i]; self.fish_timers[i - 1] = self.fish_timers[i];
} }
self.fish_timers[SPAWNING_DELAY as usize - 1] += newly_spawned; self.fish_timers[SPAWNING_DELAY - 1] += newly_spawned;
*self.fish_timers.last_mut().unwrap() = newly_spawned; *self.fish_timers.last_mut().unwrap() = newly_spawned;
} }
fn size(&self) -> usize { fn size(&self) -> usize {
self.fish_timers.iter().sum() self.fish_timers.iter().sum()
} }
fn grow_for(&mut self, turns: usize) -> usize {
for _ in 0..turns {
self.next_turn();
}
self.size()
}
} }
impl std::str::FromStr for School { impl std::str::FromStr for School {
type Err = anyhow::Error; type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> { fn from_str(s: &str) -> Result<Self> {
let mut fish_timers = [0usize; SPAWNING_DELAY as usize + 2]; let mut fish_timers = [0usize; SPAWNING_DELAY + 2];
for fish in s.split(',').map(str::parse::<usize>) { for fish in s.split(',').map(str::parse::<usize>) {
let fish = fish?; fish_timers[fish?] += 1;
fish_timers[fish] += 1;
} }
Ok(School { fish_timers }) Ok(School { fish_timers })
} }
} }
impl std::str::FromStr for LanternFish {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
Ok(LanternFish { timer: s.parse()? })
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;