diff --git a/2016/rust/src/day_05.rs b/2016/rust/src/day_05.rs index d513244..ee74246 100644 --- a/2016/rust/src/day_05.rs +++ b/2016/rust/src/day_05.rs @@ -1,4 +1,5 @@ use std::char; +use std::collections::HashMap; use crypto::digest::Digest; use crypto::md5::Md5; @@ -6,8 +7,17 @@ use crypto::md5::Md5; use errors::*; pub fn solve(input: &str) -> Result { - let pw = Password::new(input.trim()); - Ok(pw.take(8).collect()) + let mut pw = Password::new(input.trim()); + let mut solution = HashMap::new(); + while solution.len() < 8 { + let candidate = pw.next().unwrap(); + if candidate.0 < 8 { + solution.entry(candidate.0).or_insert(candidate.1); + } + } + let mut v = solution.iter().collect::>(); + v.sort(); + Ok(v.iter().map(|x| *x.1).collect::()) } struct Password { @@ -23,11 +33,9 @@ impl Password { } impl Iterator for Password { - // we will be counting with usize - type Item = char; + type Item = (usize, char); - // next() is the only required method - fn next(&mut self) -> Option { + fn next(&mut self) -> Option<(usize, char)> { let mut result = None; let mut hash = [0; 16]; @@ -39,12 +47,10 @@ impl Iterator for Password { self.md5.result(&mut hash); self.md5.reset(); - if self.index % 1000000 == 0 { - println!("{}", self.index); - } - if hash[0] as u16 + hash[1] as u16 + (hash[2] >> 4) as u16 == 0 { - result = Some(char::from_digit((hash[2] & 0b00001111) as u32, 16).unwrap()); + let pos = (hash[2] & 0b00001111) as usize; + let c = char::from_digit((hash[3] >> 4) as u32, 16).unwrap(); + result = Some((pos, c)); break } } @@ -55,10 +61,10 @@ impl Iterator for Password { #[test] fn test_password() { let mut pw = Password{id: "abc".into(), index: 3231928, md5: Md5::new()}; - assert_eq!(pw.next(), Some('1'.into())); + assert_eq!(pw.next(), Some((1, '5'.into()))); assert_eq!(pw.index, 3231930); let mut pw = Password{id: "abc".into(), index: 5017308, md5: Md5::new()}; - assert_eq!(pw.next(), Some('8'.into())); - assert_eq!(pw.next(), Some('f'.into())); + assert_eq!(pw.next(), Some((8, 'f'.into()))); + // assert_eq!(pw.next(), Some((4, 'e'.into()))); }