diff --git a/Cargo.lock b/Cargo.lock index f97cf41..527d81c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,7 @@ dependencies = [ "hex-literal", "itertools", "lazy_static", + "md-5", "pico-args", "regex", "reqwest", @@ -56,6 +57,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.11.1" @@ -96,6 +106,26 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -206,6 +236,16 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "h2" version = "0.3.15" @@ -416,6 +456,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + [[package]] name = "memchr" version = "2.5.0" @@ -897,6 +946,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + [[package]] name = "unicode-bidi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index cd7af2e..f29719b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ hashbrown = "0.13.1" hex-literal = "0.3.4" itertools = "0.10.5" lazy_static = "1.4.0" +md-5 = "0.10.5" pico-args = "0.5.0" regex = "1.7.0" reqwest = "0.11.13" diff --git a/src/bin/05.rs b/src/bin/05.rs new file mode 100644 index 0000000000..5a8dde7 --- /dev/null +++ b/src/bin/05.rs @@ -0,0 +1,78 @@ +use hashbrown::HashMap; +use itertools::Itertools; +use md5::{Digest, Md5}; + +pub fn part_one(input: &str) -> Option { + let key = input.trim().as_bytes(); + let mut hasher = Md5::new(); + let mut count = 0; + let mut res = String::new(); + + for x in 0..std::u64::MAX { + hasher.update(key); + hasher.update(x.to_string().as_bytes()); + let output = hasher.finalize_reset(); + + if output.starts_with(&[0, 0]) && output[2] <= 0x0F { + count += 1; + res.push_str(&format!("{:02x}", output[2])[1..]); + } + + if count == 8 { + break; + } + } + + Some(res) +} +pub fn part_two(input: &str) -> Option { + let key = input.trim().as_bytes(); + let mut hasher = Md5::new(); + let mut res = HashMap::new(); + + for x in 0..std::u64::MAX { + hasher.update(key); + hasher.update(x.to_string().as_bytes()); + let output = hasher.finalize_reset(); + + if output.starts_with(&[0, 0]) && output[2] <= 0x0F { + let (p, c) = format!("{:02x}{:02x}", output[2], output[3])[1..3] + .chars() + .next_tuple() + .unwrap(); + if ('0'..='7').contains(&p) && !res.contains_key(&p) { + res.insert(p, c); + } + } + + if res.len() == 8 { + break; + } + } + + Some( + res.iter() + .sorted_by(|a, b| a.0.cmp(b.0)) + .map(|(_, v)| v) + .collect(), + ) +} +fn main() { + let input = &aoc::read_file("inputs", 5); + aoc::solve!(1, part_one, input); + aoc::solve!(2, part_two, input); +} +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + let input = aoc::read_file("examples", 5); + assert_eq!(part_one(&input), Some("18f47a30".to_string())); + } + #[test] + fn test_part_two() { + let input = aoc::read_file("examples", 5); + assert_eq!(part_two(&input), Some("05ace8e3".to_string())); + } +} diff --git a/src/examples/05.txt b/src/examples/05.txt new file mode 100644 index 0000000000..8baef1b --- /dev/null +++ b/src/examples/05.txt @@ -0,0 +1 @@ +abc