aboutsummaryrefslogtreecommitdiff
path: root/src/2022/day11/aoc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/2022/day11/aoc.cpp')
-rw-r--r--src/2022/day11/aoc.cpp206
1 files changed, 202 insertions, 4 deletions
diff --git a/src/2022/day11/aoc.cpp b/src/2022/day11/aoc.cpp
index a7edbe7..953837a 100644
--- a/src/2022/day11/aoc.cpp
+++ b/src/2022/day11/aoc.cpp
@@ -1,8 +1,206 @@
-#include "common.h"
-#include <vector>
+#include "aoc.h"
+#include <algorithm>
namespace aoc2022 {
-std::pair<int, int> day11(line_view) {
- return {0, 0};
+static int lcm = 1;
+
+void lcmf(int is[], int n) {
+ for (int i = 0; i < n; i++) {
+ lcm *= is[i];
+ }
+ int x = is[0];
+ for (int i = 1; i < n; i++) {
+ x = gcd(x, is[i]);
+ }
+ lcm /= x;
+}
+
+size_t op1(size_t n) {
+ return n / 3;
+}
+
+size_t op2(size_t n) {
+ return n % lcm;
+}
+
+void m0(size_t x, monkey* ms, func f) {
+ size_t n = x * 11;
+ n = f(n);
+ if (n % 7 == 0) {
+ ms[6].items.push_back(n);
+ ms[6].total += 1;
+ }
+ else {
+ ms[2].items.push_back(n);
+ ms[2].total += 1;
+ }
+}
+
+void m1(size_t x, monkey* ms, func f) {
+ size_t n = x + 1;
+ n = f(n);
+ if (n % 11 == 0) {
+ ms[5].items.push_back(n);
+ ms[5].total += 1;
+ }
+ else {
+ ms[0].items.push_back(n);
+ ms[0].total += 1;
+ }
}
+
+void m2(size_t x, monkey* ms, func f) {
+ size_t n = x * 7;
+ n = f(n);
+ if (n % 13 == 0) {
+ ms[4].items.push_back(n);
+ ms[4].total += 1;
+ }
+ else {
+ ms[3].items.push_back(n);
+ ms[3].total += 1;
+ }
+}
+
+void m3(size_t x, monkey* ms, func f) {
+ size_t n = x + 3;
+ n = f(n);
+ if (n % 3 == 0) {
+ ms[1].items.push_back(n);
+ ms[1].total += 1;
+ }
+ else {
+ ms[7].items.push_back(n);
+ ms[7].total += 1;
+ }
+}
+
+void m4(size_t x, monkey* ms, func f) {
+ size_t n = x + 6;
+ n = f(n);
+ if (n % 17 == 0) {
+ ms[3].items.push_back(n);
+ ms[3].total += 1;
+ }
+ else {
+ ms[7].items.push_back(n);
+ ms[7].total += 1;
+ }
+}
+
+void m5(size_t x, monkey* ms, func f) {
+ size_t n = x + 5;
+ n = f(n);
+ if (n % 2 == 0) {
+ ms[0].items.push_back(n);
+ ms[0].total += 1;
+ }
+ else {
+ ms[6].items.push_back(n);
+ ms[6].total += 1;
+ }
+}
+
+void m6(size_t x, monkey* ms, func f) {
+ size_t n = x * x;
+ n = f(n);
+ if (n % 5 == 0) {
+ ms[2].items.push_back(n);
+ ms[2].total += 1;
+ }
+ else {
+ ms[4].items.push_back(n);
+ ms[4].total += 1;
+ }
+}
+
+void m7(size_t x, monkey* ms, func f) {
+ size_t n = x + 7;
+ n = f(n);
+ if (n % 19 == 0) {
+ ms[5].items.push_back(n);
+ ms[5].total += 1;
+ }
+ else {
+ ms[1].items.push_back(n);
+ ms[1].total += 1;
+ }
+}
+
+
+void play(func f, monkey* m, monkey* ms) {
+ if (m->todo != nullptr) {
+ while (m->total-- > 0) {
+ int x = m->items.front();
+ m->items.pop_front();
+ m->count += 1;
+ m->todo(x, ms, f);
+ }
+ }
+}
+
+void round(func f, monkey* ms) {
+ for(int i = 0; i < 8; i++) {
+ play(f, ms+i, ms);
+ }
+ for(int i = 0; i < 8; i++) {
+ monkey* m = ms + i;
+ m->update_total();
+ }
+}
+
+size_t twobad(monkey* ms) {
+ std::sort(ms, ms+8, [](monkey& m1, monkey& m2){
+ return m1.count > m2.count;
+ });
+ return (size_t) ms[0].count * (size_t) ms[1].count;
+}
+
+void items(int r, monkey* ms) {
+ printf("round %d\n", r);
+ for(int i = 0; i < 8; i++) {
+ monkey* m = ms + i;
+ if (m->todo != nullptr) {
+ for (auto& i : m->items) {
+ printf("%zu ", i);
+ }
+ printf("\n");
+ }
+ }
+}
+
+std::pair<size_t, size_t> day11(line_view file) {
+ monkey ms1[8] = {
+ {std::vector<size_t>{63,57}, m0},
+ {std::vector<size_t>{82, 66, 87, 78, 77, 92, 83}, m1},
+ {std::vector<size_t>{97, 53, 53, 85, 58, 54}, m2},
+ {std::vector<size_t>{50}, m3},
+ {std::vector<size_t>{64, 69, 52, 65, 73}, m4},
+ {std::vector<size_t>{57, 91, 65}, m5},
+ {std::vector<size_t>{67, 91, 84, 78, 60, 69, 99, 83}, m6},
+ {std::vector<size_t>{58, 78, 69, 65}, m7},
+ };
+ monkey ms2[8] = {
+ {std::vector<size_t>{63,57}, m0},
+ {std::vector<size_t>{82, 66, 87, 78, 77, 92, 83}, m1},
+ {std::vector<size_t>{97, 53, 53, 85, 58, 54}, m2},
+ {std::vector<size_t>{50}, m3},
+ {std::vector<size_t>{64, 69, 52, 65, 73}, m4},
+ {std::vector<size_t>{57, 91, 65}, m5},
+ {std::vector<size_t>{67, 91, 84, 78, 60, 69, 99, 83}, m6},
+ {std::vector<size_t>{58, 78, 69, 65}, m7},
+ };
+
+ for (int i = 0; i < 20; i++) {
+ round(op1, ms1);
+ }
+
+ int tests[] = {7, 11, 13, 3, 17, 2, 5, 19};
+ lcmf(tests, 8);
+ for (int i = 0; i < 10000; i++) {
+ round(op2, ms2);
+ }
+ return {twobad(ms1), twobad(ms2)};
+}
+
}