This commit is contained in:
dobiadi
2024-12-18 13:26:09 +01:00
parent 017a288a3b
commit da86193181
4 changed files with 3704 additions and 0 deletions

BIN
day18/c/day18 Executable file
View File

Binary file not shown.

229
day18/c/day18.c Normal file
View File

@@ -0,0 +1,229 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

3450
day18/input.txt Normal file
View File

File diff suppressed because it is too large Load Diff

25
day18/sample.txt Normal file
View File

@@ -0,0 +1,25 @@
5,4
4,2
4,5
3,0
2,1
6,3
2,4
1,5
0,6
3,3
2,6
5,1
1,2
5,5
2,5
6,5
1,4
0,4
6,4
1,1
6,1
1,0
0,5
1,6
2,0