-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday03_part02.ixx
159 lines (134 loc) · 3.5 KB
/
day03_part02.ixx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <vector>
#include <string>
#include <regex>
#include <iostream>
#include <sstream>
#include <unordered_map>
import Utilities;
using namespace std;
export module day03_part02;
struct COORD {
string element;
int row;
int col;
};
struct REGION {
string id;
int row;
int col;
int width;
vector<COORD> neighbours;
};
static bool isSymbol(string element) {
if (Utilities::isNumber(element))
return false;
else
return element != ".";
}
static bool containsCoord(vector<COORD> coords, COORD coord) {
for (COORD c : coords) {
if (c.row == coord.row && c.col == coord.col)
return true;
}
return false;
}
static REGION buildRegion(string** schematic, int row, int col, string number, int maxRow, int maxCol) {
REGION region;
region.id = number;
region.row = row;
region.col = col;
region.width = number.length();
for (int j = col; j < (col + region.width); ++j) {
for (int dr = -1; dr <= 1; ++dr) {
for (int dc = -1; dc <= 1; ++dc) {
if (dr == 0 && dc == 0)
continue;
int checkRow = row + dr;
int checkCol = j + dc;
if (checkRow < 0 || checkRow >= maxRow || checkCol < 0 || checkCol >= maxCol) {
continue;
}
string element = schematic[checkRow][checkCol];
if (isSymbol(element)) {
COORD coord;
coord.element = element;
coord.row = checkRow;
coord.col = checkCol;
if (!containsCoord(region.neighbours, coord))
region.neighbours.push_back(coord);
}
}
}
}
return region;
}
static vector<REGION> buildRegions(string** schematic, vector<string> lines, std::regex rgx, int rows, int cols) {
int row = 0;
std::sregex_iterator end;
vector<REGION> regions;
for (string line : lines) {
std::istringstream lineStream(line);
std::string part;
// Create regex iterator for the entire string
std::sregex_iterator iter(line.begin(), line.end(), rgx);
while (iter != end) {
std::smatch match = *iter;
int colOfNumerRegion = match.position();
regions.push_back(buildRegion(schematic, row, colOfNumerRegion, match.str(), rows, cols));
++iter;
}
++row;
}
return regions;
}
static bool isNeighbour(REGION region, REGION coord) {
for (COORD neighbour : region.neighbours) {
if (neighbour.row == coord.row && neighbour.col == coord.col)
return true;
}
return false;
}
static int findCollision(vector<REGION> numbers, vector<REGION> gears) {
vector<int> collisions;
int result = 0;
for (REGION gear : gears) {
for (REGION number : numbers) {
if (isNeighbour(number, gear)) {
collisions.push_back(stoi(number.id));
}
}
if (collisions.size() == 2)
result += collisions[0] * collisions[1];
collisions.clear();
}
return result;
}
namespace day03_part02 {
export int execute() {
vector<string> lines = Utilities::readTextFile("day03/day03_input.txt");
// get numbers for regions
std::regex numbersRgx("\\d+");
std::regex gearsRgx("\\*");
// defineSchematics
int rows = lines.size();
int cols = lines[0].size();
string** engineSchematic = new string * [rows];
for (int i = 0; i < rows; ++i) {
engineSchematic[i] = new string[cols];
}
// build schematic
int row = 0;
for (string line : lines) {
int col = 0;
for (char c : line) {
engineSchematic[row][col] = std::string(1, c);
col++;
}
++row;
}
// build regions
vector<REGION> numberRegions = buildRegions(engineSchematic, lines, numbersRgx, rows, cols);
vector<REGION> gearRegions = buildRegions(engineSchematic, lines, gearsRgx, rows, cols);
return findCollision(numberRegions, gearRegions);
}
}