diff --git a/src/days.rs b/src/days.rs index 855a7cb..1e38d08 100644 --- a/src/days.rs +++ b/src/days.rs @@ -11,7 +11,7 @@ pub mod d10; pub mod d11; pub mod d12; pub mod d13; -// pub mod d14; +pub mod d14; // pub mod d15; // pub mod d16; // pub mod d17; diff --git a/src/days/d14.rs b/src/days/d14.rs new file mode 100644 index 0000000..c401448 --- /dev/null +++ b/src/days/d14.rs @@ -0,0 +1,128 @@ +use crate::prelude::*; + +pub type I = &'static str; +pub type O = usize; + +fn _parse (data: &str) -> I { + Default::default() +} + +fn _solve (data: &I) -> O { + Default::default() +} + +fn _silver (data: &I) -> O { + let mut candidates: M> = M::new(); + let mut done: Vec = vec![]; + + for i in 0.. { + let s = format!("{data}{i}"); + let hash = md5::compute(s); + let repr = format!("{:x}", hash); + + let three = repr.chars().tuple_windows().find(|&(a, b, c)| a == b && b == c); + + if let Some((c, _, _)) = three { + if !candidates.is_empty() { + let five = repr.chars().tuple_windows().find(|&(a, b, c, d, e)| a == b && a == c && a == d && a == e); + if let Some((c, _, _, _, _)) = five { + if let Some(candidates) = candidates.get_mut(&c) { + let pos = candidates.iter().position(|pos| pos + 1000 > i); + if let Some(pos) = pos { + let drained = candidates.drain(pos..).collect_vec(); + // println!("{} at: {:?} added to vec: {}", c, drained, repr); + + done.extend(drained); + candidates.clear(); + if done.len() >= 100 { // extra + done.sort(); + return done[63]; + } + } + } + + } + } + candidates.entry(c).or_default().push(i); + } + } + // 15189: too high + 0 +} + +fn _gold (data: &I) -> O { + let mut candidates: M> = M::new(); + let mut done: Vec = vec![]; + + for i in 0.. { + let s = format!("{data}{i}"); + let mut hash = md5::compute(s); + let mut repr = format!("{:x}", hash); + + for _ in 0..2016 { + hash = md5::compute(repr); + repr = format!("{:x}", hash); + } + + let three = repr.chars().tuple_windows().find(|&(a, b, c)| a == b && b == c); + + if let Some((c, _, _)) = three { + if !candidates.is_empty() { + let five = repr.chars().tuple_windows().find(|&(a, b, c, d, e)| a == b && a == c && a == d && a == e); + if let Some((c, _, _, _, _)) = five { + if let Some(candidates) = candidates.get_mut(&c) { + let pos = candidates.iter().position(|pos| pos + 1000 > i); + if let Some(pos) = pos { + let drained = candidates.drain(pos..).collect_vec(); + // println!("{} at: {:?} added to vec: {}", c, drained, repr); + + done.extend(drained); + candidates.clear(); + if done.len() >= 100 { // extra + done.sort(); + return done[63]; + } + } + } + + } + } + candidates.entry(c).or_default().push(i); + } + } + // 15189: too high + 0 +} + +#[cfg(test)] +mod test { + use super::*; + + fn read () -> I { + "qzyelonm" + } + + #[test] + fn sample () { + let data = ""; + let data = _parse(data); + + assert_eq!(1, 1) + } + + #[test] + fn silver () { + let data = read(); + let ans = _silver(&data); + + assert_eq!(ans, 15168) + } + + #[test] + fn gold () { + let data = read(); + let ans = _gold(&data); + + assert_eq!(ans, 20864) + } +}