summaryrefslogtreecommitdiffstats
path: root/day18/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'day18/__init__.py')
-rw-r--r--day18/__init__.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/day18/__init__.py b/day18/__init__.py
new file mode 100644
index 0000000..0500963
--- /dev/null
+++ b/day18/__init__.py
@@ -0,0 +1,75 @@
1# -*- coding: utf-8 -*-
2from abc import ABC
3from typing import Iterator, Set
4
5from aoc import BaseAssignment
6from aoc.datastructures import Coordinate3
7from aoc.mixins import BreathFirstSearchMixin
8
9
10class Assignment(BaseAssignment[int, Coordinate3], ABC):
11 def parse_item(self, item: str) -> Coordinate3:
12 x, y, z = item.split(",")
13 return Coordinate3(int(x), int(y), int(z))
14
15 @staticmethod
16 def open_sides(blocks: Set[Coordinate3]) -> int:
17 return len(
18 [
19 neighbour
20 for block in blocks
21 for neighbour in block.neighbours(True)
22 if neighbour not in blocks
23 ]
24 )
25
26
27class AssignmentOne(Assignment):
28 example_result = 64
29
30 def run(self, input: Iterator[Coordinate3]) -> int:
31 blocks = set(input)
32 return self.open_sides(blocks)
33
34
35class AssignmentTwo(Assignment, BreathFirstSearchMixin[Coordinate3]):
36 example_result = 58
37
38 def run(self, input: Iterator[Coordinate3]) -> int:
39 blocks = set(input)
40
41 lower_x = min([block.x for block in blocks]) - 1
42 higher_x = max([block.x for block in blocks]) + 1
43 lower_y = min([block.y for block in blocks]) - 1
44 higher_y = max([block.y for block in blocks]) + 1
45 lower_z = min([block.z for block in blocks]) - 1
46 higher_z = max([block.z for block in blocks]) + 1
47
48 all_coordinates = set(
49 Coordinate3(x, y, z)
50 for x in range(lower_x, higher_x + 1)
51 for y in range(lower_y, higher_y + 1)
52 for z in range(lower_z, higher_z + 1)
53 )
54
55 def nb(c):
56 for n in c.neighbours(True):
57 if n in all_coordinates and n not in blocks:
58 yield n
59
60 outer_coordinates = {
61 coordinate
62 for coordinate in self.bfs(
63 Coordinate3(lower_x, lower_y, lower_z),
64 neighbours=nb,
65 )
66 }
67
68 return len(
69 [
70 neighbour
71 for block in blocks
72 for neighbour in block.neighbours(True)
73 if neighbour in outer_coordinates
74 ]
75 )