blob: a9be56cbc4bee2635a8eb38cc60255586c4f62db (
plain)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
|
// Standard C++
#include <array>
#include <iostream>
#include <map>
#include <optional>
#include <string>
// Standard C
#include <cstring>
// System
#include <md5.h>
using namespace std;
namespace {
optional<char>
contains_repeating_chars(string_view str)
{
for ( size_t i = 2; i < str.size(); ++i ) {
if ( str[i] == str[i - 1] && str[i] == str[i - 2] ) {
return str[i];
}
}
return {};
}
string
md5(const string& input)
{
array<char, MD5_DIGEST_STRING_LENGTH> digest{};
MD5Data(input.data(), input.size(), digest.data());
return digest.data();
}
int
solve(const function<string(int)>& get_hash)
{
int keys = 0;
for ( int index = 0;; ++index ) {
auto hash = get_hash(index);
auto repeat = contains_repeating_chars(hash);
if ( !repeat.has_value() ) {
continue;
}
const string pattern(5, repeat.value());
for ( auto index2 = index + 1; index2 != index + 1000; ++index2 ) {
hash = get_hash(index2);
if ( hash.find(pattern) != string::npos ) {
++keys;
break;
}
}
if ( keys == 64 ) {
return index;
}
}
}
void
part1(const string& input)
{
map<int, string> cache;
auto get_hash = [&](int index) {
if ( cache.contains(index) ) {
return cache.at(index);
}
auto hash = md5(input + to_string(index));
cache.emplace(index, hash);
return hash;
};
cout << solve(get_hash) << '\n';
}
void
part2(const string& input)
{
map<int, string> cache;
auto get_hash = [&](int index) {
if ( cache.contains(index) ) {
return cache.at(index);
}
auto hash = input + to_string(index);
for ( int i = 0; i != 2017; ++i ) {
hash = md5(hash);
}
cache.emplace(index, hash);
return hash;
};
cout << solve(get_hash) << '\n';
}
} // namespace
int
main()
{
// part1("abc");
// part2("abc");
part1("qzyelonm");
part2("qzyelonm");
}
|