diff options
Diffstat (limited to 'src/2022/day11/aoc.cpp')
-rw-r--r-- | src/2022/day11/aoc.cpp | 206 |
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)}; +} + } |