Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
akp 2022-12-19 00:53:48 +00:00
parent 552a951365
commit 7846d9675f
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
7 changed files with 149 additions and 1 deletions

View file

@ -0,0 +1 @@
# [Day 18: Boiling Boulders](https://adventofcode.com/2022/day/18)

View file

@ -0,0 +1,15 @@
{
"day": 18,
"dir": "challenges/2022/18-boilingBoulders",
"implementations": {
"Python": {
"part.1.avg": 0.02251845836639404,
"part.1.max": 0.03545045852661133,
"part.1.min": 0.018925189971923828,
"part.2.avg": 0.12088701725006104,
"part.2.max": 0.1763911247253418,
"part.2.min": 0.10623359680175781
}
},
"numRuns": 200
}

View file

@ -0,0 +1,17 @@
{
"inputFile": "input.txt",
"testCases": {
"one": [
{
"input": "2,2,2\n1,2,2\n3,2,2\n2,1,2\n2,3,2\n2,2,1\n2,2,3\n2,2,4\n2,2,6\n1,2,5\n3,2,5\n2,1,5\n2,3,5\n",
"expected": "64"
}
],
"two": [
{
"input": "2,2,2\n1,2,2\n3,2,2\n2,1,2\n2,3,2\n2,2,1\n2,2,3\n2,2,4\n2,2,6\n1,2,5\n3,2,5\n2,1,5\n2,3,5\n",
"expected": "58"
}
]
}
}

View file

@ -0,0 +1,12 @@
import sys
inp = sys.stdin.read()
print(len(inp), file=sys.stderr)
print("union(){")
for line in inp.strip().splitlines():
print(f"\ttranslate([{line}]) cube(1);")
print("};")

View file

@ -0,0 +1,102 @@
from typing import *
from aocpy import BaseChallenge, foldl
Coordinate = Tuple[int, int, int]
CubeMap = Dict[Coordinate, bool]
ADJACENT_LOCATIONS = (
(1, 0, 0), (-1, 0, 0),
(0, 1, 0), (0, -1, 0),
(0, 0, 1), (0, 0, -1),
)
def sum_coordinates(ca: Coordinate, cb: Coordinate) -> Coordinate:
return tuple(a + b for (a, b) in zip(ca, cb))
def parse(instr: str) -> CubeMap:
res: CubeMap = {}
for line in instr.strip().splitlines():
res[tuple(map(int, line.split(",")))] = False
for coord in res:
is_completely_surrounded = True
for modifier in ADJACENT_LOCATIONS:
combined = sum_coordinates(coord, modifier)
is_completely_surrounded = is_completely_surrounded and combined in res
res[coord] = is_completely_surrounded
return res
def count_exposed_faces(targets: Iterable[Coordinate], all_cubes: CubeMap) -> int:
n = 0
for coord in targets:
for modifier in ADJACENT_LOCATIONS:
if sum_coordinates(coord, modifier) not in all_cubes:
n += 1
return n
def min_max(x: Iterable[int]) -> Tuple[int, int]:
mini, maxi = None, 0
for item in x:
if item > maxi:
maxi = item
if mini is None or item < mini:
mini = item
if mini is None:
raise ValueError("empty set")
return mini, maxi
def is_coord_in_range(c: Coordinate, min_c: Coordinate, max_c: Coordinate) -> bool:
return foldl(
lambda x, y: x and y,
((a <= b <= c) for (a, b, c) in zip(min_c, c, max_c)),
True,
)
class Challenge(BaseChallenge):
@staticmethod
def one(instr: str) -> int:
inp = parse(instr)
return count_exposed_faces([p for p in inp if not inp[p]], inp)
@staticmethod
def two(instr: str) -> int:
inp = parse(instr)
min_x, max_x = min_max(c[0] for c in inp)
min_y, max_y = min_max(c[1] for c in inp)
min_z, max_z = min_max(c[2] for c in inp)
min_coord = (min_x - 1, min_y - 1, min_z - 1)
max_coord = (max_x + 1, max_y + 1, max_z + 1)
visited: Dict[Coordinate, None] = {}
touchable_faces = 0
scan_points = [min_coord]
while len(scan_points) != 0:
current = scan_points.pop()
if current in visited:
continue
visited[current] = None
for modifier in ADJACENT_LOCATIONS:
combined = sum_coordinates(current, modifier)
if (not is_coord_in_range(combined, min_coord, max_coord)):
continue
if combined in inp:
touchable_faces += 1
else:
scan_points.append(combined)
return touchable_faces

View file

@ -32,4 +32,5 @@ The red dotted line denotes 15 seconds.
| 14 - Regolith Reservoir | ★ ★ | [Python](14-regolithReservoir/py/__init__.py) | Simulating falling sand |
| 15 - Beacon Exclusion Zone | ★ ★ | [Python](15-beaconExclusionZone/py/__init__.py) | Searching through a 4000000^2 size grid for a literal single empty spot |
| 16 - Proboscidea Volcanium | ★ ★ | [Python](16-proboscideaVolcanium/py/__init__.py) | Nasty combinatorics |
| 17 - Pyroclastic Flow | ★ ★ | [Python](17-pyroclasticFlow/py/__init__.py) | Detecting cycles in a large amount of knock-off Tetris. |
| 17 - Pyroclastic Flow | ★ ★ | [Python](17-pyroclasticFlow/py/__init__.py) | Detecting cycles in a large amount of knock-off Tetris. |
| 18 - Boiling Boulders | ★ ★ | [Python](18-boilingBoulders/py/__init__.py) | Finding the surface area of a shape specified by a list of unit cubes. |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Before After
Before After