-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday14.rs
108 lines (94 loc) · 3.22 KB
/
day14.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::collections::HashSet;
use std::fs;
pub(crate) fn day14() {
// gen_hashes("input/2016/day14/test.txt", "abc", 0);
// gen_hashes("input/2016/day14/input.txt", "ngcjuoqr", 0);
// gen_hashes("input/2016/day14/test_b.txt", "abc", 2016);
// gen_hashes("input/2016/day14/input_b.txt", "ngcjuoqr", 2016);
// println!("{}", solve(fs::read_to_string("input/2016/day14/test.txt").unwrap()));
// println!("{}", solve(fs::read_to_string("input/2016/day14/test_b.txt").unwrap()));
println!("{}", solve(fs::read_to_string("input/2016/day14/input.txt").unwrap()));
println!("{}", solve(fs::read_to_string("input/2016/day14/input_b.txt").unwrap()));
}
#[allow(unused)]
fn gen_hashes(path: &str, salt: &str, rep: usize) {
let mut data = String::new();
for i in 0..30000 {
let mut hash = format!("{:x}", md5::compute(format!("{}{}", salt, i)));
for i in 0..rep {
hash = format!("{:x}", md5::compute(hash));
}
data.push_str(format!("{}\n", hash).as_str());
}
fs::write(path, data).expect("Cannot write to file");
}
fn solve(input: String) -> usize {
let hashes: Vec<&str> = input.lines().collect();
let mut i = 0;
let mut key_ctr = 0;
loop {
let hash = hashes[i];
match find_triplet(hash.to_string()) {
Some(triplet) => {
for j in i + 1..=i + 1000 {
if find_quintet(hashes[j].to_string()).contains(&triplet) {
key_ctr += 1;
if key_ctr == 64 {
return i;
}
break;
}
}
}
None => {}
}
i += 1;
}
}
fn find_triplet(hash: String) -> Option<char> {
let chars: Vec<char> = hash.chars().collect();
for i in 0..chars.len() - 2 {
let a = chars[i];
let b = chars[i + 1];
let c = chars[i + 2];
if a == b && b == c {
return Some(a);
}
}
None
}
fn find_quintet(hash: String) -> HashSet<char> {
let chars: Vec<char> = hash.chars().collect();
let mut quintets = HashSet::new();
for i in 0..chars.len() - 4 {
let a = chars[i];
let b = chars[i + 1];
let c = chars[i + 2];
let d = chars[i + 3];
let e = chars[i + 4];
if a == b && b == c && c == d && d == e {
quintets.insert(a);
}
}
quintets
}
#[cfg(test)]
mod day14_tests {
use std::fs;
use crate::y2016::day14::{find_triplet, solve};
#[test]
fn find_triplet_works() {
assert_eq!(Some('8'), find_triplet("0034e0923cc38887a57bd7b1d4f953df".to_string()));
assert_eq!(None, find_triplet("65b7d651740a924bef52e4eefa46fe76".to_string()));
}
#[test]
fn test_works() {
assert_eq!(22728, solve(fs::read_to_string("input/2016/day14/test.txt").unwrap()));
assert_eq!(22551, solve(fs::read_to_string("input/2016/day14/test_b.txt").unwrap()));
}
#[test]
fn input_works() {
assert_eq!(18626, solve(fs::read_to_string("input/2016/day14/input.txt").unwrap()));
assert_eq!(20092, solve(fs::read_to_string("input/2016/day14/input_b.txt").unwrap()));
}
}