#include #include #include #include #define CHARS_MAX 6 #define MAX_BYTES 16*1024 #define QUEUE_MAX 16*1024 const int directions[][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} }; #define directions_len (sizeof(directions)/sizeof(directions[0])) int main() { char *p, *buf, c; buf = calloc(CHARS_MAX, sizeof(char)); p = buf; int (*bytes)[2] = calloc(MAX_BYTES, sizeof(bytes[0])); int byte_count = 0; while ((c = getchar()) != EOF) { *p++ = c; if (c != '\n') { continue; } p = buf; sscanf(p, "%i", &bytes[byte_count][0]); while(*p++ != ','); sscanf(p, "%i", &bytes[byte_count++][1]); memset(buf, 0, CHARS_MAX); p = buf; } free(buf); int rows, colums, first_batch; // Sample vs real life if (byte_count < 1024) { rows = 7; colums = 7; first_batch = 12; } else { rows = 71; colums = 71; first_batch = 1024; } int **map = calloc(rows, sizeof(map[0])); for (int i = 0; i < rows; i++) { map[i] = calloc(colums, sizeof(map[0][0])); } // Task 1: First batch of bytes for (int i = 0; i < first_batch; i++) { map[bytes[i][1]][bytes[i][0]] = 1; } // Shortest path search uint32_t **costs = calloc(rows, sizeof(costs[0])); for (int i = 0; i < rows; i++) { costs[i] = calloc(colums, sizeof(costs[0][0])); memset(costs[i], 255, colums * sizeof(costs[0][0])); } int (*queue)[2] = calloc(QUEUE_MAX, sizeof(queue[0])); int queue_num = 1; // Start at 0,0 queue[0][0] = 0; queue[0][1] = 0; costs[0][0] = 0; while (queue_num > 0) { // Pop first int x = queue[0][0]; int y = queue[0][1]; uint32_t cost = costs[x][y]; if (x == rows - 1 && y == colums - 1) { printf("%u\n", cost); break; } for (int i = 0; i < queue_num - 1; i++) { queue[i][0] = queue[i+1][0]; queue[i][1] = queue[i+1][1]; } queue_num--; // Check each direction for (int i = 0; i < directions_len; i++) { int dx = directions[i][0]; int dy = directions[i][1]; int next_x = x + dx; int next_y = y + dy; // Outside of map, into wall, or better path exists if (next_x < 0 || next_y < 0 || next_x >= rows || next_y >= colums || map[next_x][next_y] || costs[next_x][next_y] <= cost + 1) { continue; } // Insert into queue uint32_t next_cost = cost + 1; costs[next_x][next_y] = next_cost; int insert_idx; for (insert_idx = 0; insert_idx < queue_num; insert_idx++) { int qx = queue[insert_idx][0]; int qy = queue[insert_idx][1]; if (costs[qx][qy] > next_cost) { break; } } for (int j = queue_num; j > insert_idx; j--) { queue[j][0] = queue[j-1][0]; queue[j][1] = queue[j-1][1]; } queue[insert_idx][0] = next_x; queue[insert_idx][1] = next_y; queue_num++; } } // Second part for (int k = 1; k < byte_count; k++) { int **map = calloc(rows, sizeof(map[0])); for (int i = 0; i < rows; i++) { map[i] = calloc(colums, sizeof(map[0][0])); } for (int i = 0; i <= k; i++) { map[bytes[i][1]][bytes[i][0]] = 1; } uint32_t **costs = calloc(rows, sizeof(costs[0])); for (int i = 0; i < rows; i++) { costs[i] = calloc(colums, sizeof(costs[0][0])); memset(costs[i], 255, colums * sizeof(costs[0][0])); } int (*queue)[2] = calloc(QUEUE_MAX, sizeof(queue[0])); int queue_num = 1; // Start at 0,0 queue[0][0] = 0; queue[0][1] = 0; costs[0][0] = 0; int path_found = 0; while (queue_num > 0) { // Pop first int x = queue[0][0]; int y = queue[0][1]; uint32_t cost = costs[x][y]; if (x == rows - 1 && y == colums - 1) { path_found = 1; break; } for (int i = 0; i < queue_num - 1; i++) { queue[i][0] = queue[i+1][0]; queue[i][1] = queue[i+1][1]; } queue_num--; // Check each direction for (int i = 0; i < directions_len; i++) { int dx = directions[i][0]; int dy = directions[i][1]; int next_x = x + dx; int next_y = y + dy; // Outside of map, into wall, or better path exists if (next_x < 0 || next_y < 0 || next_x >= rows || next_y >= colums || map[next_x][next_y] || costs[next_x][next_y] <= cost + 1) { continue; } // Insert into queue uint32_t next_cost = cost + 1; costs[next_x][next_y] = next_cost; int insert_idx; for (insert_idx = 0; insert_idx < queue_num; insert_idx++) { int qx = queue[insert_idx][0]; int qy = queue[insert_idx][1]; if (costs[qx][qy] > next_cost) { break; } } for (int j = queue_num; j > insert_idx; j--) { queue[j][0] = queue[j-1][0]; queue[j][1] = queue[j-1][1]; } queue[insert_idx][0] = next_x; queue[insert_idx][1] = next_y; queue_num++; } } if (!path_found) { printf("%i,%i\n", bytes[k][0], bytes[k][1]); break; } for (int i = 0; i < rows; i++) { free(map[i]); free(costs[i]); } free(map); free(costs); } free(bytes); for (int i = 0; i < rows; i++) { free(map[i]); free(costs[i]); } free(map); free(costs); }