GRID_SIDE :: 100;
GRID_SIZE :: GRID_SIDE * GRID_SIDE * GRID_SIDE;
solve_day18 :: (test: bool) {
contents := read_entire_file(ifx test then "inputs/day18_test.txt" else "inputs/day18.txt");
lines := split(contents, cast(u8) #char "\n");
part1 := 0;
part2 := 0;
cubes: []Cube = NewArray(GRID_SIZE, Cube);
defer array_free(cubes);
for 0..cubes.count - 1 cubes[it] = .{};
max_coord: Coord = .{ 0, 0, 0 };
for line: lines {
comma := split(line, cast(u8) #char ",");
coord := Coord.{
x = string_to_int(comma[0], 10, s64) + 1,
y = string_to_int(comma[1], 10, s64) + 1,
z = string_to_int(comma[2], 10, s64) + 1,
};
max_coord.x = max(max_coord.x, coord.x);
max_coord.y = max(max_coord.y, coord.y);
max_coord.z = max(max_coord.z, coord.z);
part1 += 6;
cubes[calc_grid_index(coord)].has_lava = true;
for f: Coord.[.{1,0,0},.{-1,0,0},.{0,1,0},.{0,-1,0},.{0,0,1},.{0,0,-1}] {
if coord.x + f.x >= GRID_SIDE continue;
if coord.y + f.y >= GRID_SIDE continue;
if coord.z + f.z >= GRID_SIDE continue;
if coord.x + f.x < 0 continue;
if coord.y + f.y < 0 continue;
if coord.z + f.z < 0 continue;
cube := *cubes[calc_grid_index(f + coord)];
if cube.has_lava {
part1 -= 2;
}
}
}
max_coord += .{1,1,1};
start_coord := Coord.{0,0,0};
queue: Deque(Coord);
defer deinit(*queue);
init(*queue);
deque_add_last(*queue, start_coord);
while queue.count > 0 {
item := deque_remove_first(*queue);
if cubes[calc_grid_index(item)].visited continue;
cubes[calc_grid_index(item)].visited = true;
for f: Coord.[.{1,0,0},.{-1,0,0},.{0,1,0},.{0,-1,0},.{0,0,1},.{0,0,-1}] {
test_coord := f + item;
if !inside(test_coord, max_coord) continue;
cube := *cubes[calc_grid_index(test_coord)];
if cube.has_lava {
part2 += 1;
} else if !cube.visited {
deque_add_last(*queue, test_coord);
}
}
}
print("Part 1: %\n", part1);
print("Part 2: %\n", part2);
}
inside :: (point: Coord, max: Coord) -> bool {
return point.x >= 0 && point.x <= max.x &&
point.y >= 0 && point.y <= max.y &&
point.z >= 0 && point.z <= max.z;
}
calc_grid_index :: (coord: Coord) -> s64 {
return GRID_SIDE * GRID_SIDE * coord.z + GRID_SIDE * coord.y + coord.x;
}
#scope_file
Coord :: struct {
x: s64;
y: s64;
z: s64;
}
Cube :: struct {
has_lava: bool = false;
visited: bool = false;
}
operator + :: (c1: Coord, c2: Coord) -> Coord {
return .{ c1.x + c2.x, c1.y + c2.y, c1.z + c2.z };
}
cmp :: (c1: Coord, c2: Coord) -> bool {
return c1.x == c2.x && c1.y == c2.y && c1.z == c2.z;
}
hash :: (c: Coord) -> u32 {
return get_hash(c.x) ^ get_hash(c.y) ^ get_hash(c.z);
}