Skip to content

Latest commit

 

History

History
160 lines (121 loc) · 4.17 KB

18.md

File metadata and controls

160 lines (121 loc) · 4.17 KB

Day 18

Part 1 Part 2 Total
Time 4:02 47:06 51:08

Yay!!! I can go to bed now!

Part 1

This one was a simple "just do it" type of problem. Nice change of pace from the past few days...

from helpers.datagetter import data_in, submit
from collections import defaultdict

ans = 0
din = data_in(split=True, numbers=True)

cubes = defaultdict(int)

for line in din:
    cubes[tuple(line)] = 1


def exposed_faces(pos):
    x = pos[0]
    y = pos[1]
    z = pos[2]

    exposed = 0
    if (x + 1, y, z) not in cubes:
        exposed += 1
    if (x - 1, y, z) not in cubes:
        exposed += 1
    if (x, y + 1, z) not in cubes:
        exposed += 1
    if (x, y - 1, z) not in cubes:
        exposed += 1
    if (x, y, z + 1) not in cubes:
        exposed += 1
    if (x, y, z - 1) not in cubes:
        exposed += 1

    return exposed


print(cubes)
for cube in cubes.keys():
    ans += exposed_faces(cube)

print(ans)
submit(ans)

Part 2

For Part 2 I decided to implement a flood-fill of the outside of the obsidian structure and invert it to do the surface area counting again. I had some trouble with the flood fill logic and some maximum recursion errors, which was silly of me, but got there in the end. Just happy to be going to bed at a reasonable time! The flood-filler is poorly made so it takes a few seconds to run on my machine which should not be the case for such a simple problem. Whatever!

Also yes, the code is ugly. Keep in mind this is after a slight refactoring and getting rid of unused bits.

from helpers.datagetter import data_in, submit
from collections import defaultdict

ans = 0
din = data_in(split=True, numbers=True)

cubes = defaultdict(int)

for line in din:
    cubes[tuple(line)] = 1


def exposed_faces(pos):
    global check
    x = pos[0]
    y = pos[1]
    z = pos[2]

    exposed = 0
    if (x + 1, y, z) not in cubes:
        exposed += 1
    if (x - 1, y, z) not in cubes:
        exposed += 1
    if (x, y + 1, z) not in cubes:
        exposed += 1
    if (x, y - 1, z) not in cubes:
        exposed += 1
    if (x, y, z + 1) not in cubes:
        exposed += 1
    if (x, y, z - 1) not in cubes:
        exposed += 1

    return exposed


minx, miny, minz = 100, 100, 100
maxx, maxy, maxz = 0, 0, 0

for cube in cubes.keys():
    minx = min(minx, cube[0])
    miny = min(miny, cube[1])
    minz = min(minz, cube[2])
    maxx = max(maxx, cube[0])
    maxy = max(maxy, cube[1])
    maxz = max(maxz, cube[2])
    ans += exposed_faces(cube)

new_stuff = defaultdict(int)
visited = []


def flood_fill(start):
    queue = [start]
    while queue:
        x, y, z = queue.pop(0)
        if x < minx - 1 or y < miny - 1 or z < minz - 1 or x > maxx + 1 or y > maxy + 1 or z > maxz + 1:
            continue

        if cubes[(x, y, z)] == 0:
            new_stuff[(x, y, z)] = 1

            # Eew, yuck please don't look
            if (x + 1, y, z) not in queue and (x + 1, y, z) not in visited:
                queue.append((x + 1, y, z))
                visited.append((x + 1, y, z))
            if (x - 1, y, z) not in queue and (x - 1, y, z) not in visited:
                queue.append((x - 1, y, z))
                visited.append((x - 1, y, z))
            if (x, y + 1, z) not in queue and (x, y + 1, z) not in visited:
                queue.append((x, y + 1, z))
                visited.append((x, y + 1, z))
            if (x, y - 1, z) not in queue and (x, y - 1, z) not in visited:
                queue.append((x, y - 1, z))
                visited.append((x, y - 1, z))
            if (x, y, z + 1) not in queue and (x, y, z + 1) not in visited:
                queue.append((x, y, z + 1))
                visited.append((x, y, z + 1))
            if (x, y, z - 1) not in queue and (x, y, z - 1) not in visited:
                queue.append((x, y, z - 1))
                visited.append((x, y, z - 1))


flood_fill((minx - 1, miny - 1, minz - 1))
cubes = defaultdict(int)

for i in range(minx, maxx + 1):
    for j in range(miny, maxy + 1):
        for k in range(minz, maxz + 1):
            if new_stuff[(i, j, k)] == 0:
                cubes[(i, j, k)] = 1

ans = 0
for cube in cubes.keys():
    ans += exposed_faces(cube)

print(ans)
submit(ans)