Skip to content

Commit

Permalink
[2019/15] solved
Browse files Browse the repository at this point in the history
  • Loading branch information
StarlitGhost committed Jan 2, 2024
1 parent 5ea117b commit 3ffbc65
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 2 deletions.
Binary file added .aoc_tiles/tiles/2019/15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions 2019/15/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from GhostyUtils import aoc
from GhostyUtils.intcode.cpu import IntCode
from GhostyUtils.vec2 import Vec2, Dir
from GhostyUtils.grid import Grid
from collections import deque, defaultdict


moves = Dir.map_nswe([1, 2, 3, 4])
translate = {v: k for k, v in moves.items()}


class Droid:
def __init__(self, grid: dict):
self.cpu = IntCode(aoc.read(), input=self.next_move, output=self.status)
self.pos = Vec2(0, 0)
self.grid = grid
self.last_move = Dir.N
self.reverse_path = []
self.search_space = set(self.neighbours())
self.move_queue = deque([Dir.N])

def process(self):
while self.search_space and not self.cpu.halted():
self.cpu.process()

def neighbours(self):
adjacent = [tuple(self.pos + d) for d in [Dir.N, Dir.E, Dir.S, Dir.W]]
# filter out directions that lead into walls
adjacent = [pos for pos in adjacent if self.grid[pos] != '#']
return adjacent

def next_move(self):
move = self.move_queue.popleft()
self.last_move = move
# print('next move!', move, translate[move])
return translate[move]

def status(self, code: int):
move_pos = tuple(self.pos + self.last_move)

match code:
# hit a wall
case 0:
self.grid[move_pos] = '#'
# moved
case 1:
if self.grid[move_pos] == '':
self.grid[move_pos] = '.'
self.reverse_path.append(self.last_move.flipped())
self.pos = Vec2(move_pos)
# found oxygen system
case 2:
if self.grid[move_pos] == '':
self.grid[move_pos] = 'O'
self.reverse_path.append(self.last_move.flipped())
print('p1:', len(self.reverse_path))
self.pos = Vec2(move_pos)

# remove the space we just uncovered from the search space
if move_pos in self.search_space:
self.search_space.remove(move_pos)

neighbours = [n for n in self.neighbours() if self.grid[n] == '']
if neighbours:
self.search_space.update(neighbours)
self.move_queue.append(Dir(tuple(neighbours[0] - self.pos)))
else:
# reverse our path until we find unexplored neighbours
if not self.reverse_path:
return
backwards = self.reverse_path.pop()
self.move_queue.append(backwards)


def bfs(start: tuple, grid: Grid):
frontier = [[start]]
visited = set()

while frontier:
path = frontier.pop(0)
pos = path[-1]
for new_pos in grid.neighbours(pos, diagonal=False):
if grid[new_pos] == '#' or new_pos in visited:
continue
visited.add(new_pos)
frontier.append(path + [new_pos])
return path


def main():
grid = defaultdict(str, {(0, 0): '.'})
droid = Droid(grid)

droid.process()

grid = Grid.from_sparse(grid, ' ')
start = grid.find('O')
path = bfs(start, grid)
print('p2:', len(path) - 1)


if __name__ == "__main__":
main()
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
My solutions to the yearly Advents of Code

<!-- AOC TILES BEGIN -->
<h1 align="center">
Advent of Code - 157/450 ⭐
</h1>
<h1 align="center">
2023 - 47 ⭐
</h1>
Expand Down Expand Up @@ -129,7 +132,7 @@ My solutions to the yearly Advents of Code
<img src=".aoc_tiles/tiles/2022/15.png" width="161px">
</a>
<h1 align="center">
2019 - 28
2019 - 30
</h1>
<a href="2019/1/script.py">
<img src=".aoc_tiles/tiles/2019/01.png" width="161px">
Expand Down Expand Up @@ -173,6 +176,9 @@ My solutions to the yearly Advents of Code
<a href="2019/14/script.py">
<img src=".aoc_tiles/tiles/2019/14.png" width="161px">
</a>
<a href="2019/15/script.py">
<img src=".aoc_tiles/tiles/2019/15.png" width="161px">
</a>
<h1 align="center">
2015 - 50 ⭐
</h1>
Expand Down
22 changes: 21 additions & 1 deletion utils/GhostyUtils/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ def __init__(self, data: Sequence[str], *, convert: Callable = None) -> None:
self._width = len(self.grid[0])
self._height = len(self.grid)

@staticmethod
def from_sparse(data: dict[tuple, Any], empty: Any = None) -> 'Grid':
tl = Vec2(min(data.keys(), key=lambda k: k[0])[0],
min(data.keys(), key=lambda k: k[1])[1])
br = Vec2(max(data.keys(), key=lambda k: k[0])[0],
max(data.keys(), key=lambda k: k[1])[1])
width = br.x - tl.x + 1
height = br.y - tl.y + 1
grid_list = []
for y in range(height):
grid_list.append([])
for x in range(width):
coord = (x + tl.x, y + tl.y)
value = data[coord] if coord in data else empty
grid_list[y].append(value)
grid = Grid(grid_list)
grid._offset = tl
return grid

def width(self) -> int:
return self._width

Expand Down Expand Up @@ -60,7 +79,7 @@ def in_bounds(self, position: Vec2) -> bool:
if type(position) is tuple:
position = Vec2(position)
return ((0 <= position.x < self._width) and
(0 <= position.y < self._height))
(0 <= position.y < self._height))

def neighbours(self, position: Vec2, *, diagonal: bool = True, connects: Callable = None):
if type(position) is tuple:
Expand All @@ -87,6 +106,7 @@ def overlay(obj, pos):
for o in reversed(overlays):
if pos in o and s is None:
s = str(o[pos])
break
if s is None:
s = str(obj)
return s
Expand Down

0 comments on commit 3ffbc65

Please sign in to comment.