#include #include #define GRID_SIZE 300 /* Dump a 2d array for debugging */ #define array_size(array) (sizeof array / sizeof array[0]) #define dump2d(array) \ puts(#array":"); \ for (int row = 0; row < array_size(array); row++) { \ for (int col = 0; col < array_size(array[0]); col++) { \ printf("%4d", array[row][col]); \ } \ putchar('\n'); \ } #define BAD_ARGS 1 int main(int argc, char *argv[]) { static int cells[GRID_SIZE][GRID_SIZE]; static int above[GRID_SIZE+1][GRID_SIZE]; static int left_of[GRID_SIZE][GRID_SIZE]; int grid_serial, power_level; struct { int power_level, x, y, size; } best = {INT_MIN}; if (argc < 2 || sscanf(argv[1], "%d", &grid_serial) != 1 ) { return BAD_ARGS; } /* Fill in cell power levels and check 1x1 squares */ for (int row = 0; row < GRID_SIZE; row++) { int y = row + 1; for (int col = 0; col < GRID_SIZE; col++) { int x = col + 1; int rack_id = x + 10; power_level = rack_id * y; power_level += grid_serial; power_level *= rack_id; power_level = power_level % 1000 / 100; power_level -= 5; cells[row][col] = power_level; if (power_level > best.power_level) { best.power_level = power_level; best.x = x; best.y = y; best.size = 1; } } } /* Calculate partial row and column sums */ for (int row = 1; row < GRID_SIZE; row++) { for (int col = 1; col < GRID_SIZE; col++) { above[row][col] = above[row-1][col] + cells[row-1][col]; left_of[row][col] = left_of[row][col-1] + cells[row][col-1]; } } for (int col = 1; col < GRID_SIZE; col++) { above[GRID_SIZE][col] = above[GRID_SIZE-1][col] + cells[GRID_SIZE-1][col]; } if (0) { dump2d(cells) dump2d(above) dump2d(left_of) } /* Check all squares 2x2 and up */ for (int row = 0; row < GRID_SIZE - 1; row++) { for (int col = 0; col < GRID_SIZE - 1; col++) { int limit = row < col? GRID_SIZE - col: GRID_SIZE - row; power_level = cells[row][col]; for (int grow = 1; grow < limit; grow++) { power_level += left_of[row+grow][col+grow] - left_of[row+grow][col] + above[row+grow+1][col+grow] - above[row][col+grow]; if (power_level > best.power_level) { best.power_level = power_level; best.x = col + 1; best.y = row + 1; best.size = grow + 1; } } } } printf("%d,%d,%d\n", best.x, best.y, best.size); return 0; }