aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2023-01-26 14:30:35 +0800
committerkaiwu <kaiwu2004@gmail.com>2023-01-26 14:30:35 +0800
commite9945d14975c9fe57133c67834ab65b3c48021a8 (patch)
tree949ee9504050a87c555d0213b230d6b06e1ee18a /src
parentce1b89ccb424e920447115478ae3f7fcc024608a (diff)
downloadadvent-of-code-e9945d14975c9fe57133c67834ab65b3c48021a8.tar.gz
advent-of-code-e9945d14975c9fe57133c67834ab65b3c48021a8.zip
2016 day21 part1
Diffstat (limited to 'src')
-rw-r--r--src/2016/day21/README.md5
-rw-r--r--src/2016/day21/aoc.cpp166
2 files changed, 170 insertions, 1 deletions
diff --git a/src/2016/day21/README.md b/src/2016/day21/README.md
index 9d6aa4c..6985724 100644
--- a/src/2016/day21/README.md
+++ b/src/2016/day21/README.md
@@ -26,4 +26,9 @@ After these steps, the resulting scrambled password is decab.
Now, you just need to generate a new scrambled password and you can access the system. Given the list of scrambling operations in your puzzle input, what is the result of scrambling abcdefgh?
+--- Part Two ---
+
+You scrambled the password correctly, but you discover that you can't actually modify the password file on the system. You'll need to un-scramble one of the existing passwords by reversing the scrambling process.
+
+What is the un-scrambled version of the scrambled password fbgdceah?
diff --git a/src/2016/day21/aoc.cpp b/src/2016/day21/aoc.cpp
index cf47315..8c72582 100644
--- a/src/2016/day21/aoc.cpp
+++ b/src/2016/day21/aoc.cpp
@@ -2,5 +2,169 @@
namespace aoc2016 {
-std::pair<int64_t, int64_t> day21(line_view) { return {0, 0}; }
+typedef void (*scramble)(char cs[8], int, int);
+
+static int index(char cs[8], char x) {
+ for (int i = 0; i < 8; i++) {
+ if (cs[i] == x) {
+ return i;
+ }
+ }
+ return 8;
+}
+
+// swap position X with position Y
+static void swap(char cs[8], int x, int y) { std::swap(cs[x], cs[y]); }
+
+// swap letter X with letter Y
+static void swap_char(char cs[8], int x, int y) {
+ auto xi = index(cs, (char)x);
+ auto yi = index(cs, (char)y);
+ std::swap(cs[xi], cs[yi]);
+}
+
+// rotate left/right X steps
+static void rotate(char cs[8], int left, int right) {
+ while (left-- > 0) {
+ char head = cs[0];
+ for (int i = 1; i < 8; i++) {
+ cs[i - 1] = cs[i];
+ }
+ cs[7] = head;
+ }
+ while (right-- > 0) {
+ char tail = cs[7];
+ for (int i = 6; i >= 0; i--) {
+ cs[i + 1] = cs[i];
+ }
+ cs[0] = tail;
+ }
+}
+
+// rotate based on position of letter X
+// determine the index of letter X
+// rotate the string to the right one time
+// plus a number of times equal to that index
+// plus one additional time if the index was at least 4
+static void rotate_char(char cs[8], int x, int) {
+ int i = index(cs, x);
+ rotate(cs, 0, i >= 4 ? 2 + i : 1 + i);
+}
+
+// reverse positions X through Y
+// including the letters at X and Y
+static void reverse(char cs[8], int x, int y) {
+ while (x < y) {
+ std::swap(cs[x], cs[y]);
+ x++;
+ y--;
+ }
+}
+
+// move position X to position Y
+static void move(char cs[8], int x, int y) {
+ char c = cs[x];
+ if (x > y) {
+ for (int i = x; i > y; i--) {
+ cs[i] = cs[i - 1];
+ }
+ }
+ if (x < y) {
+ for (int i = x; i < y; i++) {
+ cs[i] = cs[i + 1];
+ }
+ }
+ cs[y] = c;
+}
+
+typedef void (*parse)(const char*, int ds[2]);
+static void parse_swap(const char* p, int ds[2]) {
+ ds[0] = *(p + 14) - '0';
+ ds[1] = *(p + 30) - '0';
+}
+
+static void parse_swap_char(const char* p, int ds[2]) {
+ ds[0] = *(p + 12);
+ ds[1] = *(p + 26);
+}
+
+static void parse_rotate(const char* p, int ds[2]) {
+ if (*(p + 7) == 'l') {
+ ds[0] = *(p + 12) - '0';
+ }
+ if (*(p + 7) == 'r') {
+ ds[1] = *(p + 13) - '0';
+ }
+}
+
+static void parse_rotate_char(const char* p, int ds[2]) {
+ ds[0] = *(p + 35);
+ ds[1] = 0;
+}
+
+static void parse_reverse(const char* p, int ds[2]) {
+ ds[0] = *(p + 18) - '0';
+ ds[1] = *(p + 28) - '0';
+}
+
+static void parse_move(const char* p, int ds[2]) {
+ ds[0] = *(p + 14) - '0';
+ ds[1] = *(p + 28) - '0';
+}
+
+static void print(char* cs) {
+ for (int i = 0; i < 8; i++) {
+ auto c = cs[i];
+ printf("%c", c);
+ }
+ printf("\n");
+}
+
+std::pair<int64_t, int64_t> day21(line_view file) {
+ struct {
+ parse pf;
+ scramble sf;
+ } fs[] = {{parse_swap, swap}, {parse_swap_char, swap_char},
+ {parse_rotate, rotate}, {parse_rotate_char, rotate_char},
+ {parse_reverse, reverse}, {parse_move, move}};
+
+ char cs[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
+ per_line(
+ file,
+ [fs](line_view lv, char cs[8]) {
+ const char* p = lv.line;
+ int ds[2] = {0, 0};
+ int i = 6;
+ if (*p == 's' && *(p + 5) == 'p') {
+ i = 0;
+ }
+ if (*p == 's' && *(p + 5) == 'l') {
+ i = 1;
+ }
+ if (*p == 'r' && *(p + 1) == 'o' && *(p + 7) == 'r') {
+ i = 2;
+ }
+ if (*p == 'r' && *(p + 1) == 'o' && *(p + 7) == 'l') {
+ i = 2;
+ }
+ if (*p == 'r' && *(p + 1) == 'o' && *(p + 7) == 'b') {
+ i = 3;
+ }
+ if (*p == 'r' && *(p + 1) == 'e') {
+ i = 4;
+ }
+ if (*p == 'm') {
+ i = 5;
+ }
+ fs[i].pf(p, ds);
+ fs[i].sf(cs, ds[0], ds[1]);
+ print(cs);
+ return true;
+ },
+ cs);
+
+ print(cs);
+ return {0, 0};
+}
+
} // namespace aoc2016