add day 14

This commit is contained in:
timeshifter
2026-07-01 23:10:03 +02:00
parent e28ff1dd22
commit 7f1b82f7db
3 changed files with 139 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day14"
version = "0.1.0"
dependencies = [
"itertools",
"md5",
]
[[package]]
name = "either"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]]
name = "itertools"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
dependencies = [
"either",
]
[[package]]
name = "md5"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0"
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "day14"
version = "0.1.0"
edition = "2024"
[dependencies]
md5 = "0.8.0"
itertools = "*"
+99
View File
@@ -0,0 +1,99 @@
use std::collections::VecDeque;
use itertools::Itertools;
#[cfg(debug_assertions)]
const INPUT: &str = "abc";
#[cfg(not(debug_assertions))]
const INPUT: &str = "ihaygndm";
fn main() {
part_1();
part_2();
}
fn part_2() {
let mut next_hashes = VecDeque::new();
let mut idx = 0;
let mut found_key_counter = 0;
loop {
while next_hashes.len() < 1_000 {
next_hashes.push_back(calculate_hash_repeated(INPUT, idx, 2016));
idx += 1;
}
let this_hash = next_hashes.pop_front().unwrap();
if let Some(found_char) = find_triple_char(&this_hash)
&& next_hashes
.iter()
.any(|s| contains_quintuple(s.as_str(), found_char))
{
found_key_counter += 1;
if found_key_counter == 64 {
println!("{}", idx - 1000);
break;
}
}
}
}
fn part_1() {
let mut next_hashes = VecDeque::new();
let mut idx = 0;
let mut found_key_counter = 0;
loop {
while next_hashes.len() < 1_000 {
next_hashes.push_back(calculate_hash(INPUT, idx));
idx += 1;
}
let this_hash = next_hashes.pop_front().unwrap();
if let Some(found_char) = find_triple_char(&this_hash)
&& next_hashes
.iter()
.any(|s| contains_quintuple(s.as_str(), found_char))
{
found_key_counter += 1;
if found_key_counter == 64 {
println!("{}", idx - 1000);
break;
}
}
}
}
fn calculate_hash(s: &str, idx: usize) -> String {
format!("{:x}", md5::compute(format!("{s}{idx}")))
}
fn calculate_hash_repeated(s: &str, idx: usize, count: usize) -> String {
let mut hash = calculate_hash(s, idx);
for _ in 0..count {
hash = format!("{:x}", md5::compute(hash));
}
hash
}
fn find_triple_char(s: &str) -> Option<char> {
s.chars()
.tuple_windows()
.filter(|(a, b, c)| a == b && b == c)
.map(|(c, _, _)| c)
.next()
}
fn contains_quintuple(s: &str, value: char) -> bool {
s.chars().tuple_windows().any(|(a, b, c, d, e)| {
let head = a;
[b, c, d, e].into_iter().all(|ch| head == ch) // all items are identical
&& head == value
})
}