Line data Source code
1 : #include "PuzzleImpl.h"
2 :
3 : #include "Grid2d.h"
4 : #include "Regex.h"
5 : #include "Vector.h"
6 :
7 : #include <fmt/format.h>
8 : #include <fmt/ranges.h>
9 :
10 : #include <chrono>
11 : #include <thread>
12 :
13 : #include <numeric>
14 :
15 : namespace {
16 :
17 : constexpr Vec2<int64_t> bathroomSize{101, 103};
18 :
19 : struct Robot {
20 : Vec2<int64_t> p;
21 : Vec2<int64_t> v;
22 : };
23 :
24 1 : std::vector<Robot> parse(std::string_view const input) {
25 1 : std::vector<Robot> result;
26 1 : std::string regex = R"(p=(\d+),(\d+) v=(-?\d+),(-?\d+))";
27 1 : FindAndConsume<int64_t, int64_t, int64_t, int64_t> consume(regex);
28 500 : for (auto [px, py, vx, vy] : consume(input)) {
29 500 : result.emplace_back(Vec2<int64_t>{px, py}, Vec2<int64_t>{vx, vy});
30 500 : }
31 1 : return result;
32 1 : }
33 :
34 : } // namespace
35 :
36 1 : template <> size_t part1<2024, 14>(std::string_view const input) {
37 1 : std::vector<Robot> const robots = parse(input);
38 :
39 1 : constexpr Vec2<int64_t> center = bathroomSize / 2;
40 1 : std::array<unsigned, 4u> quadrantCount{};
41 :
42 1 : constexpr int seconds = 100;
43 :
44 500 : for (auto &r : robots) {
45 500 : Vec2<int64_t> p = ((r.p + seconds * r.v) % bathroomSize + bathroomSize) % bathroomSize;
46 500 : if (p.x() > center.x()) {
47 235 : if (p.y() > center.y()) {
48 128 : ++quadrantCount[0];
49 128 : } else if (p.y() < center.y()) {
50 104 : ++quadrantCount[1];
51 104 : }
52 265 : } else if (p.x() < center.x()) {
53 259 : if (p.y() > center.y()) {
54 118 : ++quadrantCount[2];
55 141 : } else if (p.y() < center.y()) {
56 138 : ++quadrantCount[3];
57 138 : }
58 259 : }
59 500 : }
60 :
61 1 : return std::ranges::fold_left(quadrantCount, int64_t(1), std::multiplies{});
62 1 : }
63 :
64 1 : template <> size_t part2<2024, 14>(std::string_view const) {
65 :
66 : // Code used for pattern evaluation with HI
67 :
68 : // std::vector<Robot> const robots = parse(input);
69 :
70 : // Grid2d<char> pic(bathroomSize, ' ');
71 : // auto const flippedPicView = pic.flipY();
72 :
73 : // constexpr int fps = 10;
74 : // constexpr std::chrono::duration<double> frameTime{1.0 / fps};
75 :
76 : // // for (int i = 90; i <= 6888; i += 103) { // horizontal pattern
77 : // // for (int i = 20; i <= 6888; i += 101) { // vertical pattern
78 : // for (int i = 0; i <= 6888; ++i) { // all frames
79 : // auto const frameStart = std::chrono::steady_clock::now();
80 : // pic.fill(' ');
81 : // for (auto &r : robots) {
82 : // Vec2<int64_t> p = ((r.p + i * r.v) % bathroomSize + bathroomSize) % bathroomSize;
83 : // pic[p] = 'X';
84 : // }
85 : // fmt::println("Time: {}s\n:{}\n\n\n", i, flippedPicView);
86 : // std::this_thread::sleep_until(frameStart + frameTime);
87 : // }
88 :
89 1 : return 6888;
90 1 : }
|