diff --git a/day 12/day_12_felix.cpp b/day 12/day_12_felix.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6b3b246b5a3f42e2a4e4f6c10fce848f5f863062 --- /dev/null +++ b/day 12/day_12_felix.cpp @@ -0,0 +1,136 @@ +#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