Browse Source

Optimize day 9

master
mid-kid 3 years ago
parent
commit
0781905565
  1. 50
      d09.cc
  2. BIN
      d09_bigboy.txt.xz

50
d09.cc

@ -12,12 +12,17 @@ struct map2d {
unsigned height; unsigned height;
}; };
struct coord2d {
int y;
int x;
};
auto parse_input(char *file) auto parse_input(char *file)
{ {
ifstream input(file); ifstream input(file);
if (!input.is_open()) exit(1); if (!input.is_open()) exit(1);
struct map2d map; map2d map;
unsigned width = 0; unsigned width = 0;
for (string line; getline(input, line);) { for (string line; getline(input, line);) {
@ -33,7 +38,7 @@ auto parse_input(char *file)
return map; return map;
} }
char getpoint2d(struct map2d input, int y, int x) char getpoint2d(map2d & input, int y, int x)
{ {
auto map = getmap2d(input); auto map = getmap2d(input);
if (y < 0 || x < 0) return 9; if (y < 0 || x < 0) return 9;
@ -47,7 +52,7 @@ int surr[][2] = {
{ 1, 0}, { 1, 0},
}; };
bool is_lowest(struct map2d input, int y, int x) bool is_lowest(map2d & input, int y, int x)
{ {
char base = getpoint2d(input, y, x); char base = getpoint2d(input, y, x);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -57,23 +62,27 @@ bool is_lowest(struct map2d input, int y, int x)
return true; return true;
} }
unsigned part1(auto input) unsigned part1(auto input, vector<coord2d> & lowpoints)
{ {
unsigned lowpoints = 0;
for (unsigned y = 0; y < input.height; y++) { for (unsigned y = 0; y < input.height; y++) {
for (unsigned x = 0; x < input.width; x++) { for (unsigned x = 0; x < input.width; x++) {
if (is_lowest(input, y, x)) { if (is_lowest(input, y, x)) {
char height = getpoint2d(input, y, x); coord2d coord = {(int)y, (int)x};
lowpoints += height + 1; lowpoints.push_back(coord);
} }
} }
} }
return lowpoints; auto map = getmap2d(input);
unsigned total = 0;
for (coord2d coord : lowpoints) {
total += map[coord.y][coord.x] + 1;
}
return total;
} }
unsigned recurse_basin(struct map2d input, unordered_set<unsigned> & basin, int y, int x) unsigned recurse_basin(map2d & input, unordered_set<unsigned> & basin, int y, int x)
{ {
if (basin.contains(y * input.width + x)) return 0; if (basin.contains(y * input.width + x)) return 0;
basin.insert(y * input.width + x); basin.insert(y * input.width + x);
@ -85,24 +94,22 @@ unsigned recurse_basin(struct map2d input, unordered_set<unsigned> & basin, int
int new_x = x + surr[i][1]; int new_x = x + surr[i][1];
char cmp = getpoint2d(input, new_y, new_x); char cmp = getpoint2d(input, new_y, new_x);
if (cmp >= 9) continue; if (cmp >= 9) continue;
if (cmp > base) size += recurse_basin(input, basin, new_y, new_x); if (cmp >= base) size += recurse_basin(input, basin, new_y, new_x);
} }
return size; return size;
} }
unsigned part2(auto input) uint64_t part2(auto input, vector<coord2d> lowpoints)
{ {
unsigned biggest[4] = {0}; unsigned biggest[4] = {0};
for (unsigned y = 0; y < input.height; y++) { for (coord2d coord : lowpoints) {
for (unsigned x = 0; x < input.width; x++) { unordered_set<unsigned> basin;
unordered_set<unsigned> basin; biggest[0] = recurse_basin(input, basin, coord.y, coord.x);
biggest[0] = recurse_basin(input, basin, y, x); sort(biggest, biggest + 4);
sort(biggest, biggest + 4);
}
} }
return biggest[1] * biggest[2] * biggest[3]; return (uint64_t)biggest[1] * biggest[2] * biggest[3];
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -110,6 +117,7 @@ int main(int argc, char *argv[])
if (argc <= 1) return 1; if (argc <= 1) return 1;
auto input = parse_input(argv[1]); auto input = parse_input(argv[1]);
cout << part1(input) << endl; vector<coord2d> lowpoints;
cout << part2(input) << endl; cout << part1(input, lowpoints) << endl;
cout << part2(input, lowpoints) << endl;
} }

BIN
d09_bigboy.txt.xz

Binary file not shown.
Loading…
Cancel
Save