From 67556848bdabcfecb728d01146034889b6e731d4 Mon Sep 17 00:00:00 2001 From: maneatingape <44142177+maneatingape@users.noreply.github.com> Date: Sat, 25 Nov 2023 19:01:29 +0100 Subject: [PATCH] Year 2017 Day 15 --- README.md | 1 + benches/benchmark.rs | 1 + src/lib.rs | 1 + src/main.rs | 1 + src/year2017/day15.rs | 39 ++++++++++++++++++++++++++++++++++++ tests/test.rs | 1 + tests/year2017/day15_test.rs | 17 ++++++++++++++++ 7 files changed, 61 insertions(+) create mode 100644 src/year2017/day15.rs create mode 100644 tests/year2017/day15_test.rs diff --git a/README.md b/README.md index e81bdb1..168c839 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro | 12 | [Digital Plumber](https://adventofcode.com/2017/day/12) | [Source](src/year2017/day12.rs) | 59 | | 13 | [Packet Scanners](https://adventofcode.com/2017/day/13) | [Source](src/year2017/day13.rs) | 2 | | 14 | [Disk Defragmentation](https://adventofcode.com/2017/day/14) | [Source](src/year2017/day14.rs) | 422 | +| 15 | [Dueling Generators](https://adventofcode.com/2017/day/15) | [Source](src/year2017/day15.rs) | 425000 | ## 2016 diff --git a/benches/benchmark.rs b/benches/benchmark.rs index de10511..8b6f235 100644 --- a/benches/benchmark.rs +++ b/benches/benchmark.rs @@ -115,6 +115,7 @@ mod year2017 { benchmark!(year2017, day12); benchmark!(year2017, day13); benchmark!(year2017, day14); + benchmark!(year2017, day15); } mod year2019 { diff --git a/src/lib.rs b/src/lib.rs index 119880c..f87888b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,6 +97,7 @@ pub mod year2017 { pub mod day12; pub mod day13; pub mod day14; + pub mod day15; } /// # Rescue Santa from deep space with a solar system adventure. diff --git a/src/main.rs b/src/main.rs index 6c9b024..d83d4b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,6 +162,7 @@ fn year2017() -> Vec { solution!(year2017, day12), solution!(year2017, day13), solution!(year2017, day14), + solution!(year2017, day15), ] } diff --git a/src/year2017/day15.rs b/src/year2017/day15.rs new file mode 100644 index 0000000..8a45b65 --- /dev/null +++ b/src/year2017/day15.rs @@ -0,0 +1,39 @@ +//! # Dueling Generators +//! +//! Simple but slow solution, implementing each generator as an [`Iterator`]. +use crate::util::iter::*; +use crate::util::parse::*; +use std::iter::from_fn; + +type Input = [u64; 2]; + +pub fn parse(input: &str) -> Input { + input.iter_unsigned().chunk::<2>().next().unwrap() +} + +pub fn part1(input: &Input) -> usize { + let first = generator(input[0], 16807); + let second = generator(input[1], 48271); + judge(first, second, 40_000_000) +} + +pub fn part2(input: &Input) -> usize { + let first = generator(input[0], 16807).filter(|&a| a % 4 == 0); + let second = generator(input[1], 48271).filter(|&b| b % 8 == 0); + judge(first, second, 5_000_000) +} + +fn generator(mut state: u64, factor: u64) -> impl Iterator { + from_fn(move || { + state = (state * factor) % 0x7fffffff; + Some(state) + }) +} + +fn judge( + first: impl Iterator, + second: impl Iterator, + items: usize, +) -> usize { + first.zip(second).take(items).filter(|&(a, b)| a & 0xffff == b & 0xffff).count() +} diff --git a/tests/test.rs b/tests/test.rs index 4eed497..6edbd84 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -99,6 +99,7 @@ mod year2017 { mod day12_test; mod day13_test; mod day14_test; + mod day15_test; } mod year2019 { diff --git a/tests/year2017/day15_test.rs b/tests/year2017/day15_test.rs new file mode 100644 index 0000000..899d4ce --- /dev/null +++ b/tests/year2017/day15_test.rs @@ -0,0 +1,17 @@ +use aoc::year2017::day15::*; + +const EXAMPLE: &str = "\ +Generator A starts with 65 +Generator B starts with 8921"; + +#[test] +fn part1_test() { + let input = parse(EXAMPLE); + assert_eq!(part1(&input), 588); +} + +#[test] +fn part2_test() { + let input = parse(EXAMPLE); + assert_eq!(part2(&input), 309); +}