add day 14
This commit is contained in:
Generated
+32
@@ -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"
|
||||
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day14"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
md5 = "0.8.0"
|
||||
itertools = "*"
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user