aboutsummaryrefslogtreecommitdiff
path: root/2024
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-12-13 10:28:14 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2024-12-13 10:28:14 +0100
commitec95deb6f565d7994876932834489e7a22e19e11 (patch)
treee5a1a252561ac4d4a84eba74f048405aa6d64a98 /2024
parent77552dcbbb3281246358b24092c4e51156982ac3 (diff)
downloadaoc-ec95deb6f565d7994876932834489e7a22e19e11.tar.gz
aoc-ec95deb6f565d7994876932834489e7a22e19e11.zip
Day 12 2024, cleaned up part b
Diffstat (limited to '2024')
-rw-r--r--2024/12/Makefile24
-rw-r--r--2024/12/day12a.cpp149
-rw-r--r--2024/12/day12b.cpp159
3 files changed, 332 insertions, 0 deletions
diff --git a/2024/12/Makefile b/2024/12/Makefile
new file mode 100644
index 0000000..500a766
--- /dev/null
+++ b/2024/12/Makefile
@@ -0,0 +1,24 @@
1CC=g++ -std=c++20 -g -Wall
2
3a:
4 ${CC} -o a.out day12a.cpp
5
6b:
7 ${CC} -o b.out day12b.cpp
8
9clean:
10 rm -f a b
11
12atest: a
13 ./a.out
14
15btest: b
16 ./b.out
17
18arun: a
19 ./a.out < input
20
21brun: b
22 ./b.out < input
23
24.PHONY: a b clean atest btest arun brun
diff --git a/2024/12/day12a.cpp b/2024/12/day12a.cpp
new file mode 100644
index 0000000..b972fd2
--- /dev/null
+++ b/2024/12/day12a.cpp
@@ -0,0 +1,149 @@
1/*
2This code is a bit ugly, day12b.cpp contains a nicer implementation
3(the perimeter part is of course different).
4*/
5
6#include <iostream>
7#include <algorithm>
8#include <string>
9#include <string_view>
10#include <vector>
11using namespace std;
12
13enum class Direction { U, D, R, L };
14Direction all_directions[] = {
15 Direction::U, Direction::D, Direction::R, Direction::L,
16};
17
18pair<int, int> step(pair<int, int> p, Direction d) {
19 auto [i, j] = p;
20
21 switch (d) {
22 case Direction::U:
23 return make_pair(i-1, j);
24 case Direction::D:
25 return make_pair(i+1, j);
26 case Direction::R:
27 return make_pair(i, j+1);
28 case Direction::L:
29 return make_pair(i, j-1);
30 }
31
32 return make_pair(-999,-999);
33}
34
35class Board {
36public:
37 const char out_of_bound = '$';
38 int M, N;
39
40 Board(vector<string> &lines) {
41 N = lines.size();
42 M = 0;
43 for (string l : lines)
44 M = max(M, (int)l.size());
45 region = new int[M * N];
46 cells = new char[M * N];
47 for (int i = 0; i < N; i++) {
48 for (int j = 0; j < M; j++) {
49 region[N*i + j] = -1;
50 cells[N*i + j] = j < (int)lines[i].size() ?
51 lines[i][j] : out_of_bound;
52 }
53 }
54
55 }
56
57 ~Board() {
58 delete []region;
59 delete []cells;
60 }
61
62 char operator[](pair<int, int> p) {
63 int c = coord(p);
64 return c == -1 ? out_of_bound : cells[c];
65 }
66
67 int& reg(pair<int, int> p) {
68 return region[coord(p)];
69 }
70
71private:
72 char *cells;
73 int *region;
74
75 int coord(pair<int, int> p) {
76 auto [i, j] = p;
77 return i >= N || i < 0 || j >= M || j < 0 ? -1 : N*i + j;
78 }
79};
80
81void fill(pair<int, int> p, char a, int r, Board &board) {
82 if (board[p] != a || board.reg(p) == r)
83 return;
84 board.reg(p) = r;
85
86 fill(step(p, Direction::U), a, r, board);
87 fill(step(p, Direction::D), a, r, board);
88 fill(step(p, Direction::R), a, r, board);
89 fill(step(p, Direction::L), a, r, board);
90}
91
92int cell_perim(Board &board, pair<int, int> p) {
93 int perim = 0;
94 if (board[step(p, Direction::U)] != board[p]) perim++;
95 if (board[step(p, Direction::D)] != board[p]) perim++;
96 if (board[step(p, Direction::R)] != board[p]) perim++;
97 if (board[step(p, Direction::L)] != board[p]) perim++;
98 return perim;
99}
100
101int measure_region(Board &board, int r) {
102 int area = 0;
103 int perim = 0;
104 pair<int, int> p;
105 for (p.first = 0; p.first < board.N; p.first++) {
106 for (p.second = 0; p.second < board.M; p.second++) {
107 if (board.reg(p) == r) {
108 area++;
109 perim += cell_perim(board, p);
110 }
111 }
112 }
113
114 return area * perim;
115}
116
117int scan(Board &board, int maxr) {
118 int tot = 0;
119 for (int r = 0; r < maxr; r++)
120 tot += measure_region(board, r);
121
122 return tot;
123}
124
125int main() {
126 string line;
127 vector<string> lines;
128 while (getline(cin, line))
129 lines.push_back(line);
130
131 Board board(lines);
132
133 pair<int, int> p;
134 int r = 0;
135 for (p.first = 0; p.first < board.N; p.first++) {
136 for (p.second = 0; p.second < board.M; p.second++) {
137 if (board.reg(p) == -1) {
138 fill(p, board[p], r, board);
139 r++;
140 }
141 }
142 }
143
144 auto tot = scan(board, r);
145
146 cout << tot << endl;
147
148 return 0;
149}
diff --git a/2024/12/day12b.cpp b/2024/12/day12b.cpp
new file mode 100644
index 0000000..4078fa7
--- /dev/null
+++ b/2024/12/day12b.cpp
@@ -0,0 +1,159 @@
1#include <iostream>
2#include <cstdint>
3#include <algorithm>
4#include <string>
5#include <string_view>
6#include <vector>
7#include <set>
8using namespace std;
9
10class Direction {
11public:
12 const int U, R;
13
14 Direction(const int i, const int j) : U{ i }, R{ j } {}
15
16 Direction turnright() const {
17 return turn(-1, 0);
18 }
19
20 Direction turnleft() const {
21 return turn(1, 0);
22 }
23
24 bool operator<(const Direction& d) const { // For set<Direction>
25 return this->U < d.U || (this->U == d.U && this->R < d.R);
26 }
27private:
28 Direction turn(int64_t sin, int64_t cos) const {
29 return Direction(cos * U - sin * R, sin * U + cos * R);
30 }
31};
32
33class Position {
34public:
35 int64_t i, j;
36
37 Position(int64_t a, int64_t b) : i{a}, j{b} {}
38
39 Position step(const Direction d) const {
40 return Position(i+d.U, j+d.R);
41 }
42};
43
44const Direction all_directions[] = {
45 Direction(1, 0), Direction(-1, 0), Direction(0, 1), Direction(0, -1)
46};
47
48class Board {
49public:
50 int64_t N, M;
51 vector<int64_t> region_area;
52
53 Board(const vector<string>& lines) :
54 N{static_cast<int64_t>(lines.size())},
55 M{static_cast<int64_t>(lines[0].size())},
56 region_area(M*N), cells(M*N), region(M*N), visited(M*N)
57 {
58 for (int64_t i = 0; i < N; i++) {
59 for (int64_t j = 0; j < M; j++) {
60 region[N*i+j] = -1;
61 cells[N*i+j] = lines[i][j];
62 }
63 }
64 }
65
66 char& operator[](const Position p) {
67 if (const auto c = coord(p); c == -1)
68 return out_of_bound;
69 else
70 return cells[c];
71 }
72
73 int64_t& reg(const Position p) {
74 if (const auto c = coord(p); c == -1)
75 return out_of_region;
76 else
77 return region[c];
78 }
79
80 void fill(const Position p, const int64_t r) {
81 reg(p) = r;
82 region_area[r]++;
83 for (const auto d : all_directions)
84 if (auto q = p.step(d);
85 (*this)[q] == (*this)[p] && reg(q) != r)
86 fill(q, r);
87 }
88
89 int64_t compute_perim(int64_t r) {
90 int count = 0;
91 for (Position p(0, 0); p.i < N; p.i++)
92 for (p.j = 0; p.j < M; p.j++)
93 for (Direction d : all_directions)
94 if (reg(p) == r && reg(p.step(d)) != r)
95 count += walk(p, d);
96
97 return count;
98 }
99
100private:
101 char out_of_bound = '$';
102 int64_t out_of_region = -1;
103
104 vector<char> cells;
105 vector<int64_t> region;
106 vector<set<Direction>> visited;
107
108 int64_t coord(const Position p) const {
109 auto [i, j] = p;
110 return i >= N || i < 0 || j >= M || j < 0 ? -1 : N * i + j;
111 }
112
113 bool is_visited(const Position p, const Direction d) const {
114 if (auto c = coord(p); c == -1)
115 return false;
116 else
117 return visited[c].count(d) > 0;
118 }
119
120 void set_visited(const Position p, const Direction d) {
121 if (auto c = coord(p); c != -1)
122 visited[c].insert(d);
123 }
124
125 int64_t walk(const Position p, const Direction d) {
126 const auto r = reg(p);
127 for (auto q = p; reg(q) == r && reg(q.step(d)) != r;
128 q = q.step(d.turnleft())) {
129 if (is_visited(q, d))
130 return 0;
131 set_visited(q, d);
132 }
133
134 return 1;
135 }
136};
137
138int main() {
139 string line;
140 vector<string> lines;
141 while (getline(cin, line))
142 lines.push_back(line);
143
144 Board board(lines);
145
146 int64_t r = 0;
147 for (Position p(0, 0); p.i < board.N; p.i++)
148 for (p.j = 0; p.j < board.M; p.j++)
149 if (board.reg(p) == -1)
150 board.fill(p, r++);
151
152 int64_t tot = 0;
153 for (int64_t i = 0; i < r; i++)
154 tot += board.region_area[i] * board.compute_perim(i);
155
156 cout << tot << endl;
157
158 return 0;
159}

Generated with cgit - Back to sebastiano.tronto.net