Compare commits

..

3 commits

Author SHA1 Message Date
Antoine Martin bb9265657b 2021: day06: refacto 2021-12-06 11:34:54 +01:00
Antoine Martin 7cffb7cdc6 2021: day06: bench 2021-12-06 11:25:08 +01:00
Antoine Martin 0e4c121ebd 2021: day06: tests 2021-12-06 11:24:54 +01:00
3 changed files with 41 additions and 63 deletions

View file

@ -5,6 +5,7 @@ use aoc2021::day02;
use aoc2021::day03; use aoc2021::day03;
use aoc2021::day04; use aoc2021::day04;
use aoc2021::day05; use aoc2021::day05;
use aoc2021::day06;
fn aoc2021_all(c: &mut Criterion) { fn aoc2021_all(c: &mut Criterion) {
c.bench_function("day01", |b| b.iter(|| day01::run().unwrap())); c.bench_function("day01", |b| b.iter(|| day01::run().unwrap()));
@ -12,6 +13,7 @@ fn aoc2021_all(c: &mut Criterion) {
c.bench_function("day03", |b| b.iter(|| day03::run().unwrap())); c.bench_function("day03", |b| b.iter(|| day03::run().unwrap()));
c.bench_function("day04", |b| b.iter(|| day04::run().unwrap())); c.bench_function("day04", |b| b.iter(|| day04::run().unwrap()));
c.bench_function("day05", |b| b.iter(|| day05::run().unwrap())); c.bench_function("day05", |b| b.iter(|| day05::run().unwrap()));
c.bench_function("day06", |b| b.iter(|| day06::run().unwrap()));
} }
criterion_group! { criterion_group! {

View file

@ -0,0 +1 @@
3,4,3,1,2

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,37 +42,60 @@ 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 { #[cfg(test)]
type Err = anyhow::Error; mod tests {
use super::*;
fn from_str(s: &str) -> Result<Self> { const PROVIDED: &str = include_str!("../input/day06_provided.txt");
Ok(LanternFish { timer: s.parse()? })
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 5934);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 350149);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 26984457539);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1590327954513);
} }
} }
#[cfg(test)]
mod tests {}