This commit is contained in:
HoLLy 2021-12-06 19:37:52 +01:00
Родитель afc20bfd6e
Коммит 99790e94a9
8 изменённых файлов: 195 добавлений и 2 удалений

9
Cargo.lock сгенерированный
Просмотреть файл

@ -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"

16
day-6/Cargo.toml Normal file
Просмотреть файл

@ -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

42
day-6/benches/bench.rs Normal file
Просмотреть файл

@ -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);

1
day-6/input.txt Normal file
Просмотреть файл

@ -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

1
day-6/sample.txt Normal file
Просмотреть файл

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

126
day-6/src/main.rs Normal file
Просмотреть файл

@ -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]));
}