aboutsummaryrefslogtreecommitdiff
path: root/2016/src/day21.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-10-23 19:28:20 +0200
committerThomas Schmucker <ts@its1.de>2025-10-23 19:28:20 +0200
commitae1e96f10b399266825e275ca4a8100ceede9cad (patch)
tree707fee5d979ed37504909faad921a2e6711b1cc6 /2016/src/day21.cpp
parent0450ecd6a67226ddbaeedde64ef45dfdd72cddd1 (diff)
downloadadvent-of-code-ae1e96f10b399266825e275ca4a8100ceede9cad.tar.gz
advent-of-code-ae1e96f10b399266825e275ca4a8100ceede9cad.tar.bz2
advent-of-code-ae1e96f10b399266825e275ca4a8100ceede9cad.zip
days 19-25, aoc 2016
Diffstat (limited to '2016/src/day21.cpp')
-rw-r--r--2016/src/day21.cpp222
1 files changed, 222 insertions, 0 deletions
diff --git a/2016/src/day21.cpp b/2016/src/day21.cpp
new file mode 100644
index 0000000..7e8fed7
--- /dev/null
+++ b/2016/src/day21.cpp
@@ -0,0 +1,222 @@
1#include <algorithm>
2#include <filesystem>
3#include <fstream>
4#include <iostream>
5#include <ranges>
6#include <sstream>
7#include <string>
8#include <vector>
9
10using namespace std;
11
12namespace {
13
14void
15swap_at_pos(string& str, size_t x, size_t y)
16{
17 if ( str.empty() ) {
18 return;
19 }
20
21 swap(str.at(x), str.at(y));
22}
23
24void
25swap_letter(string& str, char x, char y)
26{
27 if ( str.empty() ) {
28 return;
29 }
30
31 for ( auto& chr: str ) {
32 if ( chr == x ) {
33 chr = y;
34 }
35 else if ( chr == y ) {
36 chr = x;
37 }
38 }
39}
40
41void
42rotate_left(string& str, size_t n)
43{
44 if ( str.empty() ) {
45 return;
46 }
47
48 ranges::rotate(str, str.begin() + static_cast<int>(n % str.size()));
49}
50
51void
52rotate_right(string& str, size_t n)
53{
54 if ( str.empty() ) {
55 return;
56 }
57
58 rotate_left(str, str.size() - n);
59}
60
61void
62rotate(string& str, char chr)
63{
64 if ( str.empty() ) {
65 return;
66 }
67
68 const auto idx = str.find(chr);
69 if ( idx == string::npos ) {
70 return;
71 }
72
73 const auto steps = 1 + idx + (idx >= 4 ? 1 : 0);
74 rotate_right(str, steps % str.size());
75}
76
77void
78reverse(string& str, size_t x, size_t y)
79{
80 if ( str.empty() ) {
81 return;
82 }
83
84 if ( x > y ) {
85 swap(x, y);
86 }
87
88 reverse(str.begin() + static_cast<string::difference_type>(x),
89 str.begin() + static_cast<string::difference_type>(y) + 1);
90}
91
92void
93move(string& str, size_t x, size_t y)
94{
95 if ( str.empty() ) {
96 return;
97 }
98
99 const auto chr = str.at(x);
100
101 str.erase(x, 1);
102 str.insert(y, 1, chr);
103}
104
105vector<string>
106readLines(const filesystem::path& filename)
107{
108 ifstream file{ filename };
109 vector<string> lines;
110
111 for ( string line; getline(file, line); ) {
112 lines.emplace_back(line);
113 }
114
115 return lines;
116}
117
118vector<string>
119split(const string& line, char sep = ' ')
120{
121 vector<string> words;
122 stringstream input{ line };
123
124 for ( string word; getline(input, word, sep); ) {
125 words.emplace_back(word);
126 }
127
128 return words;
129}
130
131void
132part1(const vector<string>& lines, string str)
133{
134 for ( const auto& line: lines ) {
135 auto words = split(line);
136
137 if ( line.starts_with("swap position") ) {
138 swap_at_pos(str, stoull(words.at(2)), stoull(words.at(5)));
139 }
140 else if ( line.starts_with("swap letter") ) {
141 swap_letter(str, words.at(2).at(0), words.at(5).at(0));
142 }
143 else if ( line.starts_with("rotate left") ) {
144 rotate_left(str, stoull(words.at(2)));
145 }
146 else if ( line.starts_with("rotate right") ) {
147 rotate_right(str, stoull(words.at(2)));
148 }
149 else if ( line.starts_with("rotate based") ) {
150 rotate(str, words.at(6).at(0));
151 }
152 else if ( line.starts_with("reverse") ) {
153 reverse(str, stoull(words.at(2)), stoull(words.at(4)));
154 }
155 else if ( line.starts_with("move") ) {
156 move(str, stoull(words.at(2)), stoull(words.at(5)));
157 }
158 else {
159 cerr << "unknown command: " << line << '\n';
160 return;
161 }
162 }
163 cout << str << '\n';
164}
165
166void
167part2(const vector<string>& lines, string str)
168{
169 for ( const auto& line: ranges::reverse_view(lines) ) {
170 auto words = split(line);
171
172 if ( line.starts_with("swap position") ) {
173 swap_at_pos(str, stoull(words.at(2)), stoull(words.at(5)));
174 }
175 else if ( line.starts_with("swap letter") ) {
176 swap_letter(str, words.at(2).at(0), words.at(5).at(0));
177 }
178 else if ( line.starts_with("rotate left") ) {
179 rotate_right(str, stoull(words.at(2)));
180 }
181 else if ( line.starts_with("rotate right") ) {
182 rotate_left(str, stoull(words.at(2)));
183 }
184 else if ( line.starts_with("rotate based") ) {
185 auto chr = words.at(6).at(0);
186 for ( size_t i = 0; i != str.size(); ++i ) {
187 string tmp = str;
188 rotate_left(tmp, i);
189
190 auto idx = tmp.find(chr);
191 auto steps = (1 + idx + (idx >= 4 ? 1 : 0));
192
193 if ( ((steps - i + str.size()) % str.size()) == 0 ) {
194 str = tmp;
195 break;
196 }
197 }
198 }
199 else if ( line.starts_with("reverse") ) {
200 reverse(str, stoull(words.at(2)), stoull(words.at(4)));
201 }
202 else if ( line.starts_with("move") ) {
203 move(str, stoull(words.at(5)), stoull(words.at(2)));
204 }
205 else {
206 cerr << "unknown command: " << line << '\n';
207 return;
208 }
209 }
210 cout << str << '\n';
211}
212
213} // namespace
214
215int
216main()
217{
218 auto lines = readLines("data/day21.txt");
219
220 part1(lines, "abcdefgh");
221 part2(lines, "fbgdceah");
222}