diff --git a/day19/src/main.rs b/day19/src/main.rs index aae7211..c1ae352 100644 --- a/day19/src/main.rs +++ b/day19/src/main.rs @@ -1,12 +1,57 @@ +use std::thread::Builder; + #[cfg(debug_assertions)] const LENGTH: usize = 5; #[cfg(not(debug_assertions))] const LENGTH: usize = 3_017_957; fn main() { - let builder = std::thread::Builder::new().stack_size(100_000_000); + let builder = new_thread_builder(); let handle = builder.spawn(part_1).unwrap(); handle.join().unwrap(); + + let builder = new_thread_builder(); + let handle = builder.spawn(part_2).unwrap(); + handle.join().unwrap(); +} + +fn part_2() { + let mut next = [0usize; LENGTH]; + for (idx, val) in next.iter_mut().enumerate() { + *val = (idx + 1) % LENGTH; + } + + let mut pointer = 0; + let mut length = LENGTH; + + // walk to the elf across from pointer, tracking its predecessor + let mut before_across = 0; + for _ in 0..(length / 2 - 1) { + before_across = next[before_across]; + } + let mut across = next[before_across]; + + loop { + let hops = if length % 2 == 1 { 2 } else { 1 }; + + // remove `across` by relinking through its predecessor + next[before_across] = next[across]; + length -= 1; + + if length == 1 { + println!("{}", pointer + 1); + break; + } + + pointer = next[pointer]; + + for i in 0..hops { + across = next[before_across]; + if i + 1 < hops { + before_across = across; + } + } + } } fn part_1() { @@ -30,3 +75,7 @@ fn part_1() { } } } + +fn new_thread_builder() -> Builder { + std::thread::Builder::new().stack_size(100_000_000) +}