Add day 6 solution
This commit is contained in:
Родитель
afc20bfd6e
Коммит
99790e94a9
|
@ -217,7 +217,14 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"aoc-lib",
|
||||
"criterion",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day-6"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc-lib",
|
||||
"criterion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -6,4 +6,5 @@ members = [
|
|||
"day-3",
|
||||
"day-4",
|
||||
"day-5",
|
||||
"day-6",
|
||||
]
|
||||
|
|
|
@ -7,7 +7,6 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
aoc-lib = { path = "../aoc-lib" }
|
||||
itertools = "0.10.1"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "day-6"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
aoc-lib = { path = "../aoc-lib" }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
|
@ -0,0 +1,42 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use aoc_lib::AdventOfCode;
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
#[path = "../src/main.rs"]
|
||||
mod main;
|
||||
|
||||
fn bench_main(c: &mut Criterion) {
|
||||
c.bench_function("parse input", |b| {
|
||||
let input = include_str!("../input.txt");
|
||||
b.iter(|| main::Day6::parse_input(black_box(input)))
|
||||
});
|
||||
|
||||
c.bench_function("solve 1", |b| {
|
||||
let input = main::Day6::parse_input(include_str!("../input.txt"));
|
||||
b.iter(|| main::Day6::solve_1(black_box(&input)))
|
||||
});
|
||||
|
||||
c.bench_function("solve 2", |b| {
|
||||
let input = main::Day6::parse_input(include_str!("../input.txt"));
|
||||
b.iter(|| main::Day6::solve_2(black_box(&input)))
|
||||
});
|
||||
|
||||
c.bench_function("parse sample input", |b| {
|
||||
let input = include_str!("../sample.txt");
|
||||
b.iter(|| main::Day6::parse_input(black_box(input)))
|
||||
});
|
||||
|
||||
c.bench_function("solve 1 (sample input)", |b| {
|
||||
let input = main::Day6::parse_input(include_str!("../sample.txt"));
|
||||
b.iter(|| main::Day6::solve_1(black_box(&input)))
|
||||
});
|
||||
|
||||
c.bench_function("solve 2 (sample input)", |b| {
|
||||
let input = main::Day6::parse_input(include_str!("../sample.txt"));
|
||||
b.iter(|| main::Day6::solve_2(black_box(&input)))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_main);
|
||||
criterion_main!(benches);
|
|
@ -0,0 +1 @@
|
|||
1,3,1,5,5,1,1,1,5,1,1,1,3,1,1,4,3,1,1,2,2,4,2,1,3,3,2,4,4,4,1,3,1,1,4,3,1,5,5,1,1,3,4,2,1,5,3,4,5,5,2,5,5,1,5,5,2,1,5,1,1,2,1,1,1,4,4,1,3,3,1,5,4,4,3,4,3,3,1,1,3,4,1,5,5,2,5,2,2,4,1,2,5,2,1,2,5,4,1,1,1,1,1,4,1,1,3,1,5,2,5,1,3,1,5,3,3,2,2,1,5,1,1,1,2,1,1,2,1,1,2,1,5,3,5,2,5,2,2,2,1,1,1,5,5,2,2,1,1,3,4,1,1,3,1,3,5,1,4,1,4,1,3,1,4,1,1,1,1,2,1,4,5,4,5,5,2,1,3,1,4,2,5,1,1,3,5,2,1,2,2,5,1,2,2,4,5,2,1,1,1,1,2,2,3,1,5,5,5,3,2,4,2,4,1,5,3,1,4,4,2,4,2,2,4,4,4,4,1,3,4,3,2,1,3,5,3,1,5,5,4,1,5,1,2,4,2,5,4,1,3,3,1,4,1,3,3,3,1,3,1,1,1,1,4,1,2,3,1,3,3,5,2,3,1,1,1,5,5,4,1,2,3,1,3,1,1,4,1,3,2,2,1,1,1,3,4,3,1,3
|
|
@ -0,0 +1 @@
|
|||
3,4,3,1,2
|
|
@ -0,0 +1,126 @@
|
|||
use aoc_lib::*;
|
||||
|
||||
aoc_setup!(Day6, sample 1: 5934, sample 2: 26984457539, part 1: 360268);
|
||||
|
||||
pub struct Day6;
|
||||
|
||||
impl AdventOfCode for Day6 {
|
||||
type Input = Vec<usize>; // can be u8
|
||||
type Output = u64;
|
||||
|
||||
fn parse_input(s: &str) -> Self::Input {
|
||||
s.split(',').map(|l| l.parse().unwrap()).collect()
|
||||
}
|
||||
|
||||
fn solve_1(input: &Self::Input) -> Self::Output {
|
||||
solve_smart::<80>(input)
|
||||
}
|
||||
|
||||
fn solve_2(input: &Self::Input) -> Self::Output {
|
||||
solve_smart::<256>(input)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve_naive<const DAYS: usize>(input: &[usize]) -> u64 {
|
||||
let mut vec: Vec<usize> = input.iter().copied().collect();
|
||||
|
||||
for _day in 0..DAYS {
|
||||
let start_len = vec.len();
|
||||
for i in 0..start_len {
|
||||
if vec[i] == 0 {
|
||||
vec[i] = 6;
|
||||
vec.push(8);
|
||||
} else {
|
||||
vec[i] -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec.len() as u64
|
||||
}
|
||||
|
||||
pub fn solve_smart<const DAYS: usize>(input: &[usize]) -> u64 {
|
||||
let map = generate_map(DAYS);
|
||||
// println!("map: {:?}", map);
|
||||
|
||||
// for every starting fish, calculate the amount of offspring they generate
|
||||
let birthed_offspring: u64 = input
|
||||
.iter()
|
||||
.map(|&fish| (map[8 - fish + DAYS])) // lower number means born earlier, means more fish
|
||||
.sum();
|
||||
|
||||
birthed_offspring // + (input.len() as u64)
|
||||
}
|
||||
|
||||
fn generate_map(days: usize) -> Vec<u64> {
|
||||
// this map contains the number of offspring that are resultant from a fish born at time 0
|
||||
// TODO: use stack array instead of vector!
|
||||
// TODO: can build this map inside a const fn!!
|
||||
let mut map = vec![0u64; (days + 8) as usize]; // + 7? + 0?
|
||||
|
||||
for day in 0..map.len() {
|
||||
let added_fish = get_fish_count_from_map_day(&map, day);
|
||||
map[day] = added_fish;
|
||||
// println!("day: {}, added_fish: {}", day, added_fish);
|
||||
}
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
// rename me
|
||||
// also const I think
|
||||
fn get_fish_count_from_map_day(map: &[u64], day: usize) -> u64 {
|
||||
// always start with 1 fish
|
||||
let mut added_fish = 1;
|
||||
|
||||
// look at all days that spawn a fish, see how many fish result from this day
|
||||
for offspring_day in (9..=day).step_by(7) {
|
||||
let remaining_days = day - offspring_day;
|
||||
added_fish += map[remaining_days];
|
||||
}
|
||||
|
||||
added_fish
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_map() {
|
||||
let map = generate_map(30 - 8);
|
||||
|
||||
assert_eq!(
|
||||
map,
|
||||
&[
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8,
|
||||
8
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_solve_naive() {
|
||||
assert_eq!(5, solve_naive::<1>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(6, solve_naive::<2>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(7, solve_naive::<3>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(9, solve_naive::<4>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_naive::<5>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_naive::<6>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_naive::<7>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_naive::<8>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(11, solve_naive::<9>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(12, solve_naive::<10>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(15, solve_naive::<11>(&[3, 4, 3, 1, 2]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_solve_smart() {
|
||||
assert_eq!(5, solve_smart::<1>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(6, solve_smart::<2>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(7, solve_smart::<3>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(9, solve_smart::<4>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_smart::<5>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_smart::<6>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_smart::<7>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(10, solve_smart::<8>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(11, solve_smart::<9>(&[3, 4, 3, 1, 2])); // fails
|
||||
assert_eq!(12, solve_smart::<10>(&[3, 4, 3, 1, 2]));
|
||||
assert_eq!(15, solve_smart::<11>(&[3, 4, 3, 1, 2]));
|
||||
}
|
Загрузка…
Ссылка в новой задаче