Line data Source code
1 : #include "Grid2d.h"
2 : #include "Intcode.h"
3 : #include "PuzzleImpl.h"
4 :
5 : #include <absl/container/flat_hash_map.h>
6 :
7 : #include <iostream>
8 : #include <limits>
9 :
10 : namespace {
11 :
12 : using Coord = Grid2d<char>::Coord;
13 :
14 : enum Dir : uint8_t { N = 0, E = 1, S = 2, W = 3 };
15 : constexpr std::array<Coord, 4u> stencil = {{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}};
16 : constexpr std::array<Dir, 4u> leftTurn = {W, N, E, S};
17 : constexpr std::array<Dir, 4u> rightTurn = {E, S, W, N};
18 :
19 : struct Instruction {
20 : bool color;
21 : bool turnLeft;
22 : };
23 :
24 2 : absl::flat_hash_map<Coord, bool> paint(std::string_view const input, int64_t startColor) {
25 2 : Computer c(input);
26 :
27 2 : Instruction i{};
28 21120 : c.registerOutput([&i, ctr = 0](int64_t v) mutable {
29 21120 : if (ctr == 0) {
30 10560 : i.color = v == 1;
31 10560 : ++ctr;
32 10560 : } else {
33 10560 : i.turnLeft = v == 0;
34 10560 : ctr = 0;
35 10560 : }
36 21120 : });
37 :
38 2 : absl::flat_hash_map<Coord, bool> paintedPanels;
39 2 : Coord coord{0, 0};
40 2 : Dir d = N;
41 2 : c.queueInput(startColor);
42 :
43 10560 : while (c.run() != Computer::HALTED) {
44 10558 : paintedPanels[coord] = i.color;
45 10558 : if (i.turnLeft)
46 5190 : d = leftTurn[d];
47 5368 : else
48 5368 : d = rightTurn[d];
49 10558 : coord += stencil[d];
50 :
51 10558 : auto it = paintedPanels.find(coord);
52 10558 : if (it == paintedPanels.end())
53 2419 : c.queueInput(0);
54 8139 : else
55 8139 : c.queueInput(it->second ? 1 : 0);
56 10558 : }
57 :
58 2 : return paintedPanels;
59 2 : }
60 :
61 0 : [[maybe_unused]] void print(absl::flat_hash_map<Coord, bool> &canvas) {
62 0 : Coord min(std::numeric_limits<Coord::ElementType>::max());
63 0 : Coord max(std::numeric_limits<Coord::ElementType>::min());
64 0 : for (auto [coord, color] : canvas) {
65 0 : if (!color)
66 0 : continue;
67 0 : min = elementwiseMin(min, coord);
68 0 : max = elementwiseMax(max, coord);
69 0 : }
70 0 : Coord extent = max - min + Coord{1, 1};
71 0 :
72 0 : Grid2d<char> grid(extent.x(), extent.y(), ' ');
73 0 :
74 0 : for (auto [coord, color] : canvas)
75 0 : if (color)
76 0 : grid[coord - min] = '#';
77 0 :
78 0 : std::cout << '\n' << grid << "\n\n";
79 0 : }
80 :
81 : } // namespace
82 :
83 1 : template <> size_t part1<2019, 11>(std::string_view const input) {
84 1 : auto paintedPanels = paint(input, 0);
85 :
86 : // print(paintedPanels);
87 :
88 1 : return paintedPanels.size();
89 1 : }
90 :
91 1 : template <> size_t part2<2019, 11>(std::string_view const input) {
92 1 : auto paintedPanels = paint(input, 1);
93 :
94 : // print(paintedPanels);
95 :
96 1 : return paintedPanels.size();
97 1 : }
|