#include "grid.h" #include "gradient.h" #include #include static void line(char const* line, grid* out) { resize(std::max(int(strlen(line)), xsize(*out)), ysize(*out) + 1, out); for (int x = 0; line[x]; ++x) (*out)[x][ysize(*out) - 1] = line[x]; } static int overlap(grid const& shape, grid const& field, int x, int y) { int out = 0; for (int sx = 0; sx < xsize(shape); ++sx) { for (int sy = 0; sy < ysize(shape); ++sy) { int fx = x + sx - xsize(shape) + 1, fy = y + sy - ysize(shape) + 1; if (fx >= 0 && fx < xsize(field) && fy >= 0 && fy < ysize(field) && shape[sx][sy] < '_' && field[fx][fy] < '_') { ++out; } } } return out; } static void check(grid const& shape, grid const& field, gradient const& grad) { for (int x = 0; x < xsize(field) + xsize(shape) - 2; ++x) { for (int y = 0; y < ysize(field) + ysize(shape) - 2; ++y) { int up = grad[UP][x][y], down = grad[DOWN][x][y + 1]; int o = overlap(shape, field, x, y), o1 = overlap(shape, field, x, y + 1); assert(up - down == o - o1); int left = grad[LEFT][x][y], right = grad[RIGHT][x + 1][y]; int o2 = overlap(shape, field, x + 1, y); assert(left - right == o - o2); } } for (int x = 0; x < xsize(field) + xsize(shape) - 1; ++x) { int ot = overlap(shape, field, x, 0), gt = grad[DOWN][x][0]; assert(ot == gt); int ob = overlap(shape, field, x, ysize(field) + ysize(shape) - 2); int gb = grad[UP][x][ysize(field) + ysize(shape) - 2]; assert(ob == gb); } for (int y = 0; y < ysize(field) + ysize(shape) - 1; ++y) { int ol = overlap(shape, field, 0, y), gl = grad[RIGHT][0][y]; assert(ol == gl); int ro = overlap(shape, field, xsize(field) + xsize(shape) - 2, y); int gr = grad[LEFT][xsize(field) + xsize(shape) - 2][y]; assert(ro == gr); } for (int sx = -2; sx <= xsize(field) + xsize(shape) + 1; ++sx) { for (int sy = -2; sy <= ysize(field) + ysize(shape) + 1; ++sy) { for (int ex = -2; ex <= xsize(field) + xsize(shape) + 1; ++ex) { for (int ey = -2; ey <= ysize(field) + ysize(shape) + 1; ++ey) { int diff = net(grad, sx, sy, ex, ey); int start = overlap(shape, field, sx, sy); int end = overlap(shape, field, ex, ey); assert(end - start == diff); } } } } } int main() { grid shape; line("_#", &shape); line("#_", &shape); line("##", &shape); tool bit; make(shape, '_', &bit); grid field; line("#____#", &field); line("_#__#_", &field); line("__##__", &field); line("_#__#_", &field); line("#____#", &field); gradient grad; make(bit, field, '_', &grad); check(shape, field, grad); for (int x = 1; x <= 4; ++x) { for (int y = 1; y <= 3; ++y) { if (field[x][y] < '_') { field[x][y] = '_'; update(bit, x, y, -1, &grad); } else { field[x][y] = '#'; update(bit, x, y, 1, &grad); } } } check(shape, field, grad); grid round; circle(5, &round); grid round_check; line("_###_", &round_check); line("#####", &round_check); line("#####", &round_check); line("#####", &round_check); line("_###_", &round_check); for (int x = 0; x < xsize(round); ++x) for (int y = 0; y < ysize(round); ++y) assert(round_check[x][y] < '_' == round[x][y] < BOTTOM); return 0; }