Skip to content

Instantly share code, notes, and snippets.

@weirddan455
Created December 19, 2022 09:45
Show Gist options
  • Save weirddan455/dc0e96757db278c6b9b7cf55fc3a0abf to your computer and use it in GitHub Desktop.
Save weirddan455/dc0e96757db278c6b9b7cf55fc3a0abf to your computer and use it in GitHub Desktop.
Advent of Code Day 18 Part 2
#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