Created
December 19, 2022 09:45
-
-
Save weirddan455/dc0e96757db278c6b9b7cf55fc3a0abf to your computer and use it in GitHub Desktop.
Advent of Code Day 18 Part 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdbool.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#define EMPTY 0 | |
#define LAVA 1 | |
#define WATER 2 | |
#define BOUNDS 3 | |
typedef struct Cube | |
{ | |
int x; | |
int y; | |
int z; | |
} Cube; | |
typedef struct CubeArray | |
{ | |
size_t size; | |
size_t capacity; | |
Cube *data; | |
} CubeArray; | |
typedef struct Grid | |
{ | |
size_t width; | |
size_t height; | |
size_t depth; | |
uint8_t *data; | |
} Grid; | |
static void parse_input(CubeArray *arr) | |
{ | |
FILE *file = fopen("input", "r"); | |
if (file == NULL) { | |
perror("fopen"); | |
exit(-1); | |
} | |
arr->size = 0; | |
arr->capacity = 16; | |
arr->data = malloc(arr->capacity * sizeof(Cube)); | |
if (arr->data == NULL) { | |
fprintf(stderr, "malloc failed\n"); | |
exit(-1); | |
} | |
while (1) { | |
if (arr->size >= arr->capacity) { | |
arr->capacity *= 2; | |
arr->data = realloc(arr->data, arr->capacity * sizeof(Cube)); | |
if (arr->data == NULL) { | |
fprintf(stderr, "realloc failed\n"); | |
exit(-1); | |
} | |
} | |
Cube *cube = arr->data + arr->size; | |
if (fscanf(file, " %d,%d,%d", &cube->x, &cube->y, &cube->z) != 3) { | |
break; | |
} | |
arr->size += 1; | |
} | |
fclose(file); | |
} | |
static void put_cube(Cube *cube, Grid *grid, uint8_t value) | |
{ | |
size_t index = (cube->z * (grid->height * grid->width)) + (cube->y * grid->width) + cube->x; | |
grid->data[index] = value; | |
} | |
static uint8_t get_cube(Cube *cube, Grid *grid) | |
{ | |
if (cube->x < 0 || cube->x >= grid->width || cube->y < 0 || cube->y >= grid->height || cube->z < 0 || cube->z >= grid->depth) { | |
return BOUNDS; | |
} | |
size_t index = (cube->z * (grid->height * grid->width)) + (cube->y * grid->width) + cube->x; | |
return grid->data[index]; | |
} | |
static void add_stack(CubeArray *stack, Cube *cube) | |
{ | |
if (stack->size >= stack->capacity) { | |
stack->capacity *= 2; | |
stack->data = realloc(stack->data, stack->capacity * sizeof(Cube)); | |
if (stack->data == NULL) { | |
fprintf(stderr, "realloc failed\n"); | |
exit(-1); | |
} | |
} | |
stack->data[stack->size] = *cube; | |
stack->size += 1; | |
} | |
int main(void) | |
{ | |
CubeArray arr; | |
parse_input(&arr); | |
Cube max; | |
max.x = arr.data[0].x; | |
max.y = arr.data[0].y; | |
max.z = arr.data[0].z; | |
for (size_t i = 1; i < arr.size; i++) { | |
Cube *cube = arr.data + i; | |
if (cube->x > max.x) { | |
max.x = cube->x; | |
} | |
if (cube->y > max.y) { | |
max.y = cube->y; | |
} | |
if (cube->z > max.z) { | |
max.z = cube->z; | |
} | |
} | |
Grid grid; | |
grid.width = max.x + 2; | |
grid.height = max.y + 2; | |
grid.depth = max.z + 2; | |
grid.data = calloc(grid.width * grid.height * grid.depth, 1); | |
if (grid.data == NULL) { | |
fprintf(stderr, "calloc failed\n"); | |
return -1; | |
} | |
for (size_t i = 0; i < arr.size; i++) { | |
put_cube(arr.data + i, &grid, LAVA); | |
} | |
free(arr.data); | |
CubeArray stack; | |
stack.size = 1; | |
stack.capacity = 16; | |
stack.data = malloc(stack.capacity * sizeof(Cube)); | |
if (stack.data == NULL) { | |
fprintf(stderr, "malloc failed\n"); | |
return -1; | |
} | |
stack.data[0].x = max.x + 1; | |
stack.data[0].y = max.y + 1; | |
stack.data[0].z = max.z + 1; | |
while (stack.size > 0) { | |
stack.size -= 1; | |
Cube cur = stack.data[stack.size]; | |
put_cube(&cur, &grid, WATER); | |
Cube test = cur; | |
test.x += 1; | |
if (get_cube(&test, &grid) == EMPTY) { | |
add_stack(&stack, &test); | |
} | |
test.x -= 2; | |
if (get_cube(&test, &grid) == EMPTY) { | |
add_stack(&stack, &test); | |
} | |
test.x = cur.x; | |
test.y += 1; | |
if (get_cube(&test, &grid) == EMPTY) { | |
add_stack(&stack, &test); | |
} | |
test.y -= 2; | |
if (get_cube(&test, &grid) == EMPTY) { | |
add_stack(&stack, &test); | |
} | |
test.y = cur.y; | |
test.z += 1; | |
if (get_cube(&test, &grid) == EMPTY) { | |
add_stack(&stack, &test); | |
} | |
test.z -= 2; | |
if (get_cube(&test, &grid) == EMPTY) { | |
add_stack(&stack, &test); | |
} | |
} | |
free(stack.data); | |
Cube itr; | |
int answer = 0; | |
for (itr.z = 0; itr.z < grid.depth; itr.z++) { | |
for (itr.y = 0; itr.y < grid.height; itr.y++) { | |
for(itr.x = 0; itr.x < grid.width; itr.x++) { | |
if (get_cube(&itr, &grid) == LAVA) { | |
Cube test = itr; | |
test.x += 1; | |
uint8_t value = get_cube(&test, &grid); | |
if (value == WATER || value == BOUNDS) { | |
answer += 1; | |
} | |
test.x -= 2; | |
value = get_cube(&test, &grid); | |
if (value == WATER || value == BOUNDS) { | |
answer += 1; | |
} | |
test.x = itr.x; | |
test.y += 1; | |
value = get_cube(&test, &grid); | |
if (value == WATER || value == BOUNDS) { | |
answer += 1; | |
} | |
test.y -= 2; | |
value = get_cube(&test, &grid); | |
if (value == WATER || value == BOUNDS) { | |
answer += 1; | |
} | |
test.y = itr.y; | |
test.z += 1; | |
value = get_cube(&test, &grid); | |
if (value == WATER || value == BOUNDS) { | |
answer += 1; | |
} | |
test.z -= 2; | |
value = get_cube(&test, &grid); | |
if (value == WATER || value == BOUNDS) { | |
answer += 1; | |
} | |
} | |
} | |
} | |
} | |
printf("Answer: %d\n", answer); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment