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 SPAWNING_DELAY: u8 = 7;
const SPAWNING_DELAY: usize = 7;
const TURNS_PART_1: usize = 80;
const TURNS_PART_2: usize = 256;
@ -19,63 +19,15 @@ pub fn run() -> Result<String> {
}
fn part1(input: &str) -> Result<usize> {
let mut school = input
.trim()
.split(',')
.map(str::parse::<LanternFish>)
.collect::<Result<Vec<_>>>()?;
let mut school = input.trim().parse::<School>()?;
for _ in 0..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())
Ok(school.grow_for(TURNS_PART_1))
}
fn part2(input: &str) -> Result<usize> {
let mut school = input.trim().parse::<School>()?;
for _ in 0..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()
}
Ok(school.grow_for(TURNS_PART_2))
}
struct School {
@ -90,38 +42,37 @@ impl School {
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;
}
fn size(&self) -> usize {
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 {
type Err = anyhow::Error;
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>) {
let fish = fish?;
fish_timers[fish] += 1;
fish_timers[fish?] += 1;
}
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)]
mod tests {
use super::*;