#include "common.h" #include namespace aoc2022 { struct rock { struct three { int minx = INT32_MAX; int maxx = INT32_MIN; int maxy = INT32_MIN; }; struct pos { int x = 0; int y = 0; pos(int xx, int yy): x(xx), y(yy) {} }; static three t3; std::vector rs; void get_number(const char** p, int ds[], int* n) { const char* p0 = *p; while (true) { while (*p0 >= '0' && *p0 <= '9') {{ ds[*n] = 10 * ds[*n] + *p0 - '0'; p0++; }} *n += 1; if (*p0 == '\n') break; else while(!(*p0 >= '0' && *p0 <= '9')) p0++; } *p = p0; } rock (line_view lv) { int is[100] = {0}; int n{0}; const char* p = lv.line; get_number(&p, is, &n); for(int i = 0; i < n; i++) { if (i % 2 == 1) { int x = is[i-1]; int y = is[i]; rs.push_back({x, y}); if (t3.minx > x) t3.minx = x; if (t3.maxx < x) t3.maxx = x; if (t3.maxy < y) t3.maxy = y; } } } void print() { for (auto& p: rs) { printf("(%d,%d) ", p.x, p.y); } printf("\n"); } }; struct cave { int width = 0; int height = 0; char* space; cave(int w, int h): width(w + 1), height(h + 1) { space = (char *) malloc(width * height); for (int i = 0; i < width * height; i++) { *(space + i) = '.'; } } cave(cave& c) { width = c.width; height = c.height; space = (char *) malloc(width * height); memcpy(space, c.space, width * height); } rock::pos to(rock::pos p) { return {p.x - rock::t3.minx, p.y}; } rock::pos to(rock::pos p, int dx) { return {p.x - rock::t3.minx + dx, p.y}; } char& get(rock::pos p) const noexcept { return *(space + p.y * width + p.x); } bool valid(rock::pos p) { return p.x >= 0 && p.x < width && p.y >= 0 && p.y < height; } rock::pos drop(rock::pos p) { rock::pos ns[] = {{p.x, p.y + 1}, {p.x - 1, p.y + 1}, {p.x + 1, p.y + 1}}; for (int i = 0; i < 3; i++) { if (valid(ns[i]) && get(ns[i]) == '.') { return drop(ns[i]); } } return p; } void mark(rock& r) { for (size_t i = 0; i < r.rs.size() - 1 ; i++) { auto r1 = r.rs[i]; auto r2 = r.rs[i+1]; if (r1.x == r2.x) { int min = r1.y < r2.y ? r1.y : r2.y; int max = r1.y > r2.y ? r1.y : r2.y; for (int j = min; j <= max; j++) { auto p = to({r1.x, j}); get(p) = '#'; } } if (r1.y == r2.y) { int min = r1.x < r2.x ? r1.x : r2.x; int max = r1.x > r2.x ? r1.x : r2.x; for (int j = min; j <= max; j++) { auto p = to({j, r1.y}); get(p) = '#'; } } } } void mark(rock& r, int dx) { for (size_t i = 0; i < r.rs.size() - 1 ; i++) { auto r1 = r.rs[i]; auto r2 = r.rs[i+1]; if (r1.x == r2.x) { int min = r1.y < r2.y ? r1.y : r2.y; int max = r1.y > r2.y ? r1.y : r2.y; for (int j = min; j <= max; j++) { auto p = to({r1.x, j}, dx); get(p) = '#'; } } if (r1.y == r2.y) { int min = r1.x < r2.x ? r1.x : r2.x; int max = r1.x > r2.x ? r1.x : r2.x; for (int j = min; j <= max; j++) { auto p = to({j, r1.y}, dx); get(p) = '#'; } } } } void print() const noexcept { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { printf("%c", get({x, y})); } printf("\n"); } } }; std::pair day14(line_view); }