Files
aoc2016/src/bin/05.rs
2023-02-01 21:48:29 +01:00

79 lines
2.0 KiB
Rust

use hashbrown::HashMap;
use itertools::Itertools;
use md5::{Digest, Md5};
pub fn part_one(input: &str) -> Option<String> {
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<String> {
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()));
}
}