From be45fce088a21eb85ab381fe89bdf9895822f9ba Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Wed, 6 Dec 2023 13:33:47 +0100 Subject: [PATCH] 2023 - Day 06 --- 2023/input/06/input | 2 + 2023/input/06/test-1 | 2 + 2023/src/bin/day06.rs | 122 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 2023/input/06/input create mode 100644 2023/input/06/test-1 create mode 100644 2023/src/bin/day06.rs diff --git a/2023/input/06/input b/2023/input/06/input new file mode 100644 index 0000000..57f1bf3 --- /dev/null +++ b/2023/input/06/input @@ -0,0 +1,2 @@ +Time: 42 68 69 85 +Distance: 284 1005 1122 1341 diff --git a/2023/input/06/test-1 b/2023/input/06/test-1 new file mode 100644 index 0000000..28f5ae9 --- /dev/null +++ b/2023/input/06/test-1 @@ -0,0 +1,2 @@ +Time: 7 15 30 +Distance: 9 40 200 diff --git a/2023/src/bin/day06.rs b/2023/src/bin/day06.rs new file mode 100644 index 0000000..184c906 --- /dev/null +++ b/2023/src/bin/day06.rs @@ -0,0 +1,122 @@ +#![feature(test)] +use anyhow::Result; +use aoc::Solver; + +// -- Runners -- +fn main() -> Result<()> { + Day::solve() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_test1() -> Result<()> { + Day::test(Day::part1, "test-1", 288) + } + + #[test] + fn part1_solution() -> Result<()> { + Day::test(Day::part1, "input", 440000) + } + + #[test] + fn part2_test1() -> Result<()> { + Day::test(Day::part2, "test-1", 71503) + } + + #[test] + fn part2_solution() -> Result<()> { + Day::test(Day::part2, "input", 26187338) + } + + // Benchmarks + extern crate test; + #[bench] + #[ignore] + fn part1_bench(b: &mut test::Bencher) { + Day::benchmark(Day::part1, b) + } + #[bench] + #[ignore] + fn part2_bench(b: &mut test::Bencher) { + Day::benchmark(Day::part2, b) + } +} + +// distance = x * (time - x) = -x^2 + x*time > record +// Solving for -x^2 + x*time - record = 0 gives times between which we win +// which we win +fn number_of_ways(time: f64, record: f64) -> usize { + let a = -1.0; + let b = time; + let c = -record; + + let one = (-b + (b.powi(2) - 4.0 * a * c).sqrt()) / (2.0 * a); + let two = (-b - (b.powi(2) - 4.0 * a * c).sqrt()) / (2.0 * a); + + (two.ceil() - one.floor() - 1.0) as usize +} + +// -- Solution -- +pub struct Day; +impl aoc::Solver for Day { + type Output1 = usize; + type Output2 = usize; + + fn day() -> u8 { + 6 + } + + fn part1(input: &str) -> Self::Output1 { + let mut lines = input.lines(); + + let times = lines + .next() + .unwrap() + .split_whitespace() + .skip(1) + .map(|num| num.parse().unwrap()); + + let records = lines + .next() + .unwrap() + .split_whitespace() + .skip(1) + .map(|num| num.parse().unwrap()); + + times + .zip(records) + .map(|(time, record)| number_of_ways(time, record)) + .product() + } + + fn part2(input: &str) -> Self::Output2 { + let mut lines = input.lines(); + + let time = lines + .next() + .unwrap() + .split_once(':') + .unwrap() + .1 + .trim() + .replace(' ', "") + .parse() + .unwrap(); + + let record = lines + .next() + .unwrap() + .split_once(':') + .unwrap() + .1 + .trim() + .replace(' ', "") + .parse() + .unwrap(); + + number_of_ways(time, record) + } +}