From 54605ed6a0ef3933fa6b2b780f2c37999e072b74 Mon Sep 17 00:00:00 2001 From: Lucas Resch Date: Sat, 9 Dec 2023 12:57:25 +0100 Subject: [PATCH] 2023-08: Solve second puzzle --- 2023-rust/README.md | 15 +++++----- 2023-rust/data/examples/08-2.txt | 10 +++++++ 2023-rust/src/bin/08.rs | 47 ++++++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 2023-rust/data/examples/08-2.txt diff --git a/2023-rust/README.md b/2023-rust/README.md index 6759861..e7fbcf4 100644 --- a/2023-rust/README.md +++ b/2023-rust/README.md @@ -9,15 +9,16 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | -| [Day 1](./src/bin/01.rs) | `63.6µs` | `628.4µs` | -| [Day 2](./src/bin/02.rs) | `43.1µs` | `49.8µs` | -| [Day 3](./src/bin/03.rs) | `431.5µs` | `425.4µs` | -| [Day 4](./src/bin/04.rs) | `96.6µs` | `19.2ms` | +| [Day 1](./src/bin/01.rs) | `64.7µs` | `631.9µs` | +| [Day 2](./src/bin/02.rs) | `41.3µs` | `47.5µs` | +| [Day 3](./src/bin/03.rs) | `425.8µs` | `424.0µs` | +| [Day 4](./src/bin/04.rs) | `97.7µs` | `19.5ms` | | [Day 5](./src/bin/05.rs) | `30.3µs` | `26.5s` | -| [Day 6](./src/bin/06.rs) | `544.0ns` | `40.8ms` | -| [Day 8](./src/bin/08.rs) | `259.2µs` | `-` | +| [Day 6](./src/bin/06.rs) | `603.0ns` | `42.7ms` | +| [Day 7](./src/bin/07.rs) | `202.3µs` | `-` | +| [Day 8](./src/bin/08.rs) | `256.0µs` | `1.8ms` | -**Total: 26562.00ms** +**Total: 26566.19ms** ## Usage diff --git a/2023-rust/data/examples/08-2.txt b/2023-rust/data/examples/08-2.txt new file mode 100644 index 0000000..5b3fa58 --- /dev/null +++ b/2023-rust/data/examples/08-2.txt @@ -0,0 +1,10 @@ +LR + +11A = (11B, XXX) +11B = (XXX, 11Z) +11Z = (11B, XXX) +22A = (22B, XXX) +22B = (22C, 22C) +22C = (22Z, 22Z) +22Z = (22B, 22B) +XXX = (XXX, XXX) diff --git a/2023-rust/src/bin/08.rs b/2023-rust/src/bin/08.rs index 6833b1e..c64da44 100644 --- a/2023-rust/src/bin/08.rs +++ b/2023-rust/src/bin/08.rs @@ -11,11 +11,19 @@ enum Direction { pub fn part_one(input: &str) -> Option { let (directions, map) = parse_input(input); + solve_part_one("AAA", &directions, &map, |node| node == "ZZZ") +} - let mut current_node = "AAA"; +fn solve_part_one( + starting_node: &str, + directions: &[Direction], + map: &HashMap<&str, (&str, &str)>, + end_condition: fn(&str) -> bool, +) -> Option { + let mut current_node = starting_node; let mut steps: u32 = 0; for direction in directions.iter().cycle() { - if current_node == "ZZZ" { + if end_condition(current_node) { break; }; steps += 1; @@ -29,8 +37,33 @@ pub fn part_one(input: &str) -> Option { Some(steps) } -pub fn part_two(input: &str) -> Option { - None +pub fn part_two(input: &str) -> Option { + let (directions, map) = parse_input(input); + + let steps_per_ghost = map + .keys() + .filter(|key| key.ends_with('A')) + .filter_map(|node| solve_part_one(node, &directions, &map, |node| node.ends_with('Z'))) + .collect_vec(); + + Some( + steps_per_ghost + .iter() + .map(|steps| *steps as u64) + .fold(1, lcm), + ) +} + +fn gcd(a: u64, b: u64) -> u64 { + if b == 0 { + a + } else { + gcd(b, a % b) + } +} + +fn lcm(a: u64, b: u64) -> u64 { + a / gcd(a, b) * b } fn parse_input(input: &str) -> (Vec, HashMap<&str, (&str, &str)>) { @@ -72,7 +105,9 @@ mod tests { #[test] fn test_part_two() { - let result = part_two(&advent_of_code::template::read_file("examples", DAY)); - assert_eq!(result, None); + let result = part_two(&advent_of_code::template::read_file_part( + "examples", DAY, 2, + )); + assert_eq!(result, Some(6)); } }