Skip to content
Snippets Groups Projects
Commit 96871d0b authored by Felix Agner's avatar Felix Agner
Browse files

added day 12

parent af415a49
No related branches found
No related tags found
No related merge requests found
#include <bits/stdc++.h>
using namespace std;
const bool DEBUG = false;
#define coord pair <int, int>
#define ll long long
const int MAX_SIZE = 200;
# define boolarray array <array <bool, MAX_SIZE>, MAX_SIZE>
const array <coord, 4> dirs = {coord(0, 1), coord(1, 0), coord(0, -1), coord(-1, 0)};
const vector<vector<coord>> orth = {
{coord(1, 0), coord(-1, 0)},
{coord(0, 1), coord(0, -1)},
{coord(1, 0), coord(-1, 0)},
{coord(0, 1), coord(0, -1)}
};
boolarray visited = {false};
vector<string> garden;
struct regionInfo{
ll area = 0;
ll perimiter = 0;
ll sides = 0;
};
void read_input() {
string line;
while (getline(cin, line)) {
garden.push_back(line);
}
}
bool is_in_bounds(coord pos) {
return pos.first >= 0 && pos.first < garden.size() && pos.second >= 0 && pos.second < garden[0].size();
}
void tag_adjacent(coord pos, boolarray &is_perimiter, boolarray &is_counted, int i) {
deque <coord> q;
q.push_back(pos);
while (!q.empty()) {
coord cur = q.front();
q.pop_front();
is_counted[cur.first+2][cur.second+2] = true;
DEBUG && cout << " Checking " << cur.first << " " << cur.second << endl;
for (coord dir : orth[i]) {
coord next = coord(cur.first + dir.first, cur.second + dir.second);
DEBUG && cout << " Next " << next.first << " " << next.second;
DEBUG && cout << " is perimiter " << is_perimiter[next.first+2][next.second+2];
DEBUG && cout << " is counted " << is_counted[next.first+2][next.second+2] << endl;
if (is_perimiter[next.first+2][next.second+2] && !is_counted[next.first+2][next.second+2]) {
q.push_back(next);
}
}
}
}
ll count_sides(vector<vector<coord>> side_pieces) {
DEBUG && cout << " Counting sides." << endl;
ll sides = 0;
for (int i = 0; i < 4; i++) {
boolarray is_perimiter = {false};
boolarray is_counted = {false};
for (coord pos : side_pieces[i]) {
is_perimiter[pos.first+2][pos.second+2] = true;
}
for (coord pos : side_pieces[i]) if (!is_counted[pos.first+2][pos.second+2]) {
sides++;
DEBUG && cout << " Side at " << pos.first << " " << pos.second << " with direction " << i << endl;
tag_adjacent(pos, is_perimiter, is_counted, i);
}
}
return sides;
}
regionInfo calculate_region(coord starting_pos) {
ll area = 0;
ll perimeter = 0;
deque <coord> q;
q.push_back(starting_pos);
char c = garden[starting_pos.first][starting_pos.second];
vector<vector<coord>> side_pieces = {{}, {}, {}, {}};
DEBUG && cout << "---------------------------------------" << endl;
DEBUG && cout << "Starting region " << c << " at " << starting_pos.first << " " << starting_pos.second << endl;
while (!q.empty()) {
coord cur = q.front();
q.pop_front();
if (visited[cur.first][cur.second]) continue;
visited[cur.first][cur.second] = true;
area++;
DEBUG && cout << " Adding " << cur.first << " " << cur.second << endl;
for (int i = 0; i < 4; i++) {
coord dir = dirs[i];
coord next = coord(cur.first + dir.first, cur.second + dir.second);
if (is_in_bounds(next) && garden[next.first][next.second] == c) {
q.push_back(next);
} else {
perimeter++;
side_pieces[i].push_back(cur);
}
}
}
ll sides = count_sides(side_pieces);
DEBUG && cout << "Region " << c << " with area " << area << ", sides " << sides << " and perimeter " << perimeter << endl;
regionInfo res = {area, perimeter, sides};
return res;
}
pair<ll,ll> solve() {
ll part1 = 0;
ll part2 = 0;
for (int i = 0; i < garden.size(); i++) for (int j = 0; j < garden[i].size(); j++) {
if (visited[i][j]) continue;
regionInfo info = calculate_region(coord(i, j));
part1 += info.area * info.perimiter;
part2 += info.area * info.sides;
}
return {part1, part2};
}
int main () {
read_input();
pair<ll,ll> res = solve();
cout << "Part 1: " << res.first << endl;
cout << "Part 2: " << res.second << endl;
return 0;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment