From f3d0899dbfd0aa3e6aebf5d19ec89d58ead418b2 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Mon, 19 Dec 2022 09:30:43 +0100 Subject: Day 18 --- day18/__init__.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 day18/__init__.py (limited to 'day18/__init__.py') 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 @@ +# -*- coding: utf-8 -*- +from abc import ABC +from typing import Iterator, Set + +from aoc import BaseAssignment +from aoc.datastructures import Coordinate3 +from aoc.mixins import BreathFirstSearchMixin + + +class Assignment(BaseAssignment[int, Coordinate3], ABC): + def parse_item(self, item: str) -> Coordinate3: + x, y, z = item.split(",") + return Coordinate3(int(x), int(y), int(z)) + + @staticmethod + def open_sides(blocks: Set[Coordinate3]) -> int: + return len( + [ + neighbour + for block in blocks + for neighbour in block.neighbours(True) + if neighbour not in blocks + ] + ) + + +class AssignmentOne(Assignment): + example_result = 64 + + def run(self, input: Iterator[Coordinate3]) -> int: + blocks = set(input) + return self.open_sides(blocks) + + +class AssignmentTwo(Assignment, BreathFirstSearchMixin[Coordinate3]): + example_result = 58 + + def run(self, input: Iterator[Coordinate3]) -> int: + blocks = set(input) + + lower_x = min([block.x for block in blocks]) - 1 + higher_x = max([block.x for block in blocks]) + 1 + lower_y = min([block.y for block in blocks]) - 1 + higher_y = max([block.y for block in blocks]) + 1 + lower_z = min([block.z for block in blocks]) - 1 + higher_z = max([block.z for block in blocks]) + 1 + + all_coordinates = set( + Coordinate3(x, y, z) + for x in range(lower_x, higher_x + 1) + for y in range(lower_y, higher_y + 1) + for z in range(lower_z, higher_z + 1) + ) + + def nb(c): + for n in c.neighbours(True): + if n in all_coordinates and n not in blocks: + yield n + + outer_coordinates = { + coordinate + for coordinate in self.bfs( + Coordinate3(lower_x, lower_y, lower_z), + neighbours=nb, + ) + } + + return len( + [ + neighbour + for block in blocks + for neighbour in block.neighbours(True) + if neighbour in outer_coordinates + ] + ) -- cgit v1.2.3