1
0
aoc-2021/src/day6.rs

83 lines
1.6 KiB
Rust

use std::num::ParseIntError;
pub fn parse_input(input: &str) -> Result<Vec<i32>, ParseIntError> {
input
.trim_end()
.split_terminator(',')
.map(|s| s.parse())
.collect()
}
fn simulate_step(fishes: &mut Vec<i32>) {
for i in 0..fishes.len() {
if fishes[i] == 0 {
fishes[i] = 7;
fishes.push(9);
}
}
for i in 0..fishes.len() {
if fishes[i] > 0 {
fishes[i] -= 1;
}
}
}
pub fn part1(input: &[i32]) -> u32 {
let mut fishes = input.to_vec();
for _ in 0..80 {
simulate_step(&mut fishes)
}
fishes.len() as u32
}
// Instead of storing each fishes cycle as individual values group them up
// by there cycles. Because it dosen't matter where the fish is in the list.
// So just make an array of size 9 for the 9 possible fish cycle timers.
// And one extra group, for accounting for the delay that when the timer is 0,
// they produce a new fish only on the next turn.
pub fn part2(input: &[i32]) -> u64 {
let mut groups: [u64; 10] = [0; 10];
for fish in input.iter() {
groups[*fish as usize + 1] += 1;
}
for _ in 0..256 {
for i in 1..10 {
groups[i - 1] += groups[i];
groups[i] = 0;
}
groups[7] += groups[0];
groups[9] += groups[0];
groups[0] = 0;
}
let mut count: u64 = 0;
for amount in groups.iter() {
count += amount;
}
count
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_example() {
let input = [3, 4, 3, 1, 2];
let result = part1(&input);
assert_eq!(result, 5934);
}
#[test]
fn part2_example() {
let input = [3, 4, 3, 1, 2];
let result = part2(&input);
assert_eq!(result, 26984457539 as u64);
}
}