From 00000180c11ab4ea3c121a564107b6b57f114230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Fri, 8 Dec 2023 08:01:05 +0100 Subject: [PATCH] solution: day 8 --- data/examples/08-1.txt | 5 +++ data/examples/08-2.txt | 10 +++++ src/bin/08.rs | 95 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 24 +++++++++++ 4 files changed, 134 insertions(+) create mode 100644 data/examples/08-1.txt create mode 100644 data/examples/08-2.txt create mode 100644 src/bin/08.rs diff --git a/data/examples/08-1.txt b/data/examples/08-1.txt new file mode 100644 index 000000000..7d1b58d --- /dev/null +++ b/data/examples/08-1.txt @@ -0,0 +1,5 @@ +LLR + +AAA = (BBB, BBB) +BBB = (AAA, ZZZ) +ZZZ = (ZZZ, ZZZ) diff --git a/data/examples/08-2.txt b/data/examples/08-2.txt new file mode 100644 index 000000000..5b3fa58 --- /dev/null +++ b/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/src/bin/08.rs b/src/bin/08.rs new file mode 100644 index 000000000..45a0a19 --- /dev/null +++ b/src/bin/08.rs @@ -0,0 +1,95 @@ +use std::collections::HashMap; + +use aoc::lcm; + +pub fn part_one(input: &str) -> Option { + let mut map = HashMap::new(); + + let (directions, map_data) = input.split_once("\n\n")?; + for line in map_data.lines() { + let (k, v) = line.split_once(" = ")?; + let v = v.strip_prefix('(')?; + let v = v.strip_suffix(')')?; + let (l, r) = v.split_once(", ")?; + + *map.entry(k).or_default() = (l, r); + } + + let mut counter = 0; + let mut loc = "AAA"; + + for d in directions.chars().cycle() { + if loc == "ZZZ" { + break; + } + + counter += 1; + let (l, r) = map[loc]; + + match d { + 'L' => loc = l, + 'R' => loc = r, + _ => unimplemented!(), + } + } + + Some(counter) +} + +pub fn part_two(input: &str) -> Option { + let mut map = HashMap::new(); + + let (directions, map_data) = input.split_once("\n\n")?; + for line in map_data.lines() { + let (k, v) = line.split_once(" = ")?; + let v = v.strip_prefix('(')?; + let v = v.strip_suffix(')')?; + let (l, r) = v.split_once(", ")?; + + *map.entry(k).or_default() = (l, r); + } + + let mut res = 1; + + for k in map.keys().filter(|x| x.ends_with('A')) { + let mut location = *k; + + for (i, d) in directions.chars().cycle().enumerate() { + let (l, r) = map[location]; + + location = match d { + 'L' => l, + 'R' => r, + _ => unimplemented!(), + }; + + if location.ends_with('Z') { + res = lcm(res, i + 1); + break; + } + } + } + + Some(res as u64) +} + +aoc::solution!(8); + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + assert_eq!( + part_one(&aoc::template::read_file_part("examples", 8, 1)), + Some(6) + ); + } + #[test] + fn test_part_two() { + assert_eq!( + part_two(&aoc::template::read_file_part("examples", 8, 2)), + Some(6) + ); + } +} diff --git a/src/lib.rs b/src/lib.rs index d103939..b1e9ad3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,28 @@ #![feature(pattern)] +use std::mem::swap; + pub mod parsers; pub mod template; + +pub fn lcm(first: usize, second: usize) -> usize { + first * second / gcd(first, second) +} + +pub fn gcd(first: usize, second: usize) -> usize { + let mut max = first; + let mut min = second; + if min > max { + swap(&mut min, &mut max) + } + + loop { + let res = max % min; + if res == 0 { + return min; + } + + max = min; + min = res; + } +}