aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2016/src/day17.cpp132
-rw-r--r--makefile3
2 files changed, 135 insertions, 0 deletions
diff --git a/2016/src/day17.cpp b/2016/src/day17.cpp
new file mode 100644
index 0000000..757a8cb
--- /dev/null
+++ b/2016/src/day17.cpp
@@ -0,0 +1,132 @@
1// Standard C++
2#include <algorithm>
3#include <array>
4#include <iostream>
5#include <map>
6#include <queue>
7#include <string>
8#include <tuple>
9
10// System
11#include <md5.h>
12
13using namespace std;
14
15namespace {
16
17using pos_type = tuple<int, int, string>;
18
19string
20md5(string_view input)
21{
22 array<char, MD5_DIGEST_STRING_LENGTH> digest{};
23 MD5Data(input.data(), input.size(), digest.data());
24 return digest.data();
25}
26
27void
28part1(const string& passcode)
29{
30 static const map<size_t, tuple<char, int, int>> dirs{
31 { 0, { 'U', 0, -1 } },
32 { 1, { 'D', 0, 1 } },
33 { 2, { 'L', -1, 0 } },
34 { 3, { 'R', 1, 0 } }
35 };
36
37 auto is_open = [](auto chr) {
38 return strchr("bcdef", chr) != nullptr;
39 };
40
41 queue<pos_type> queue;
42 queue.emplace(0, 0, "");
43
44 while ( !queue.empty() ) {
45 auto [x, y, path] = queue.front();
46 queue.pop();
47
48 if ( x == 3 && y == 3 ) {
49 cout << path << '\n';
50 return;
51 }
52
53 auto hash = md5(passcode + path);
54
55 for ( size_t i = 0; i != 4; ++i ) {
56 if ( !is_open(hash.at(i)) ) {
57 continue;
58 }
59
60 auto [chr, dx, dy] = dirs.at(i);
61
62 auto new_x = x + dx;
63 auto new_y = y + dy;
64
65 if ( new_x < 0 || new_y < 0 || new_x >= 4 || new_y >= 4 ) {
66 continue;
67 }
68
69 queue.emplace(new_x, new_y, path + chr);
70 }
71 }
72}
73
74void
75part2(const string& passcode)
76{
77 static const map<size_t, tuple<char, int, int>> dirs{
78 { 0, { 'U', 0, -1 } },
79 { 1, { 'D', 0, 1 } },
80 { 2, { 'L', -1, 0 } },
81 { 3, { 'R', 1, 0 } }
82 };
83
84 auto is_open = [](auto chr) {
85 return strchr("bcdef", chr) != nullptr;
86 };
87
88 size_t max_length = 0;
89
90 queue<pos_type> queue;
91 queue.emplace(0, 0, "");
92
93 while ( !queue.empty() ) {
94 auto [x, y, path] = queue.front();
95 queue.pop();
96
97 if ( x == 3 && y == 3 ) {
98 max_length = max(max_length, path.size());
99 continue;
100 }
101
102 auto hash = md5(passcode + path);
103
104 for ( size_t i = 0; i != 4; ++i ) {
105 if ( !is_open(hash.at(i)) ) {
106 continue;
107 }
108
109 auto [chr, dx, dy] = dirs.at(i);
110
111 auto new_x = x + dx;
112 auto new_y = y + dy;
113
114 if ( new_x < 0 || new_y < 0 || new_x >= 4 || new_y >= 4 ) {
115 continue;
116 }
117
118 queue.emplace(new_x, new_y, path + chr);
119 }
120 }
121
122 cout << max_length << '\n';
123}
124
125} // namespace
126
127int
128main()
129{
130 part1("awrkjxxr");
131 part2("awrkjxxr");
132}
diff --git a/makefile b/makefile
index ffbddf4..8e6c7c2 100644
--- a/makefile
+++ b/makefile
@@ -24,6 +24,9 @@ all: $(patsubst 2015/src/%.cpp,2015/bin/%,$(wildcard 2015/src/*.cpp)) \
242016/bin/day14: 2016/src/day14.cpp | 2016/bin 242016/bin/day14: 2016/src/day14.cpp | 2016/bin
25 c++ $(CPPFLAGS) $^ -lmd -o $@ 25 c++ $(CPPFLAGS) $^ -lmd -o $@
26 26
272016/bin/day17: 2016/src/day17.cpp | 2016/bin
28 c++ $(CPPFLAGS) $^ -lmd -o $@
29
272016/bin/day05: 2016/src/day05.cpp | 2016/bin 302016/bin/day05: 2016/src/day05.cpp | 2016/bin
28 c++ $(CPPFLAGS) $^ -lmd -o $@ 31 c++ $(CPPFLAGS) $^ -lmd -o $@
29 32