diff options
Diffstat (limited to 'solutions/py/d15.py')
| -rw-r--r-- | solutions/py/d15.py | 276 |
1 files changed, 0 insertions, 276 deletions
diff --git a/solutions/py/d15.py b/solutions/py/d15.py deleted file mode 100644 index b2a9b10..0000000 --- a/solutions/py/d15.py +++ /dev/null @@ -1,276 +0,0 @@ -import intcode -import heapq as heap -import collections -import time - -def neighbours(p): - return [(p[0]+1, p[1]), (p[0]-1, p[1]), \ - (p[0], p[1]+1), (p[0], p[1]-1)] - -def get_path(start, end, board, draw_search=False): - if start == end: - return collections.deque() - visited = set() - h = [] - heap.heappush(h, (0, start, collections.deque())) - while True: - cur = heap.heappop(h) - for n in neighbours(cur[1]): - if n == end: - cur[2].append(n) - if draw_search: - print(draw(board, path=cur[2], visited=visited)) - return cur[2] - if n in visited or n not in board or board[n] == "#": - continue - new_path = collections.deque(cur[2]) - new_path.append(n) - visited.add(n) - heap.heappush(h, (cur[0] + 1, n, new_path)) - if draw_search: - time.sleep(0.005) - print(draw(board, path=new_path, visited=visited)) - -def pt1(input): - cur_x = cur_y = 0 - q = collections.deque() - q.append((0,0)) - path = collections.deque() - board = {} - board[(0,0)] = "." - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - - while not c.SIG_HALT: - if len(q) == 0: - break - c.step() - if c.SIG_INPUT: - direction = 0 - prev_x, prev_y = cur_x, cur_y - if len(path) == 0: - # find new path - for n in neighbours((cur_x, cur_y)): - if n not in q and n not in board: - q.append(n) - if (cur_x, cur_y) in q: - q.remove((cur_x, cur_y)) - next = q.pop() - path = get_path((cur_x, cur_y), next, board) - next_step = path.popleft() - if next_step[1] == cur_y-1: - direction = 1 - cur_y -= 1 - elif next_step[1] == cur_y+1: - direction = 2 - cur_y += 1 - elif next_step[0] == cur_x-1: - direction = 3 - cur_x -= 1 - elif next_step[0] == cur_x+1: - direction = 4 - cur_x += 1 - else: - print("invalid path") - break - c.input = direction - c.SIG_INPUT = False - if c.SIG_OUTPUT: - if c.output == 0: - board[(cur_x, cur_y)] = "#" - cur_x, cur_y = prev_x, prev_y - elif c.output == 1: - board[(cur_x, cur_y)] = "." - elif c.output == 2: - board[(cur_x, cur_y)] = "S" - oxygen = (cur_x, cur_y) - else: - break - c.output = None - c.SIG_OUTPUT = False - return len(get_path((0,0), oxygen, board)) - -def pt2(input): - cur_x = cur_y = 0 - q = collections.deque() - q.append((0,0)) - path = collections.deque() - board = {} - board[(0,0)] = "." - oxygen = (0,0) - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - - while not c.SIG_HALT: - if len(q) == 0: - break - c.step() - if c.SIG_INPUT: - direction = 0 - prev_x, prev_y = cur_x, cur_y - if len(path) == 0: - # find new path - for n in neighbours((cur_x, cur_y)): - if n not in q and n not in board: - q.append(n) - if (cur_x, cur_y) in q: - q.remove((cur_x, cur_y)) - next = q.pop() - path = get_path((cur_x, cur_y), next, board) - next_step = path.popleft() - if next_step[1] == cur_y-1: - direction = 1 - cur_y -= 1 - elif next_step[1] == cur_y+1: - direction = 2 - cur_y += 1 - elif next_step[0] == cur_x-1: - direction = 3 - cur_x -= 1 - elif next_step[0] == cur_x+1: - direction = 4 - cur_x += 1 - else: - print("invalid path") - break - c.input = direction - if c.SIG_OUTPUT: - if c.output == 0: - board[(cur_x, cur_y)] = "#" - cur_x, cur_y = prev_x, prev_y - elif c.output == 1: - board[(cur_x, cur_y)] = "." - elif c.output == 2: - board[(cur_x, cur_y)] = "S" - oxygen = (cur_x, cur_y) - else: - break - c.output = None - - steps = 0 - visited = set(oxygen) - cur_layer = [] - next_layer = [oxygen] - while True: - cur_layer = next_layer.copy() - next_layer = [] - for p in cur_layer: - for n in neighbours(p): - if n in board and board[n] != "#" and n not in visited: - visited.add(n) - next_layer.append(n) - if len(next_layer) == 0: - break - steps += 1 - return steps - -def draw(board, droid=None, path=None, visited=None): - min_x=max_x=min_y=max_y = 0 - for p in board: - min_x = min(p[0], min_x) - max_x = max(p[0], max_x) - min_y = min(p[1], min_y) - max_y = max(p[1], max_y) - s = "" - for y in range(min_y-1, max_y+2): - s += "\n" - for x in range(min_x-1, max_x+2): - point = (x, y) - if droid is not None and point == droid: - s += "D" * 2 - elif path is not None and point in path: - s += "\u2591" * 2 - elif visited is not None and point in visited: - s += "." * 2 - elif point in board: - if board[point] == "#": - s += "\u2588" * 2 - elif board[point] == "S": - s += "\u2591" * 2 - else: - s += " " * 2 - else: - s += "." * 2 - return s - -def visualize(input): - cur_x = cur_y = 0 - q = collections.deque() - q.append((0,0)) - path = collections.deque() - board = {} - board[(0,0)] = "." - - c = intcode.Computer([int(x) for x in input[0].split(",")]) - - while not c.SIG_HALT: - if len(q) == 0: - break - c.step() - if c.SIG_INPUT: - direction = 0 - prev_x, prev_y = cur_x, cur_y - if len(path) == 0: - # find new path - for n in neighbours((cur_x, cur_y)): - if n not in q and n not in board: - q.append(n) - if (cur_x, cur_y) in q: - q.remove((cur_x, cur_y)) - next = q.pop() - path = get_path((cur_x, cur_y), next, board) - next_step = path.popleft() - if next_step[1] == cur_y-1: - direction = 1 - cur_y -= 1 - elif next_step[1] == cur_y+1: - direction = 2 - cur_y += 1 - elif next_step[0] == cur_x-1: - direction = 3 - cur_x -= 1 - elif next_step[0] == cur_x+1: - direction = 4 - cur_x += 1 - else: - print("invalid path") - break - c.input = direction - if c.SIG_OUTPUT: - if c.output == 0: - board[(cur_x, cur_y)] = "#" - cur_x, cur_y = prev_x, prev_y - elif c.output == 1: - board[(cur_x, cur_y)] = "." - elif c.output == 2: - board[(cur_x, cur_y)] = "S" - oxygen = (cur_x, cur_y) - else: - break - time.sleep(0.005) - print(draw(board, droid=(cur_x, cur_y))) - c.output = None - - get_path((0,0), oxygen, board, draw_search=True) - - steps = 0 - visited = set(oxygen) - cur_layer = [] - next_layer = [oxygen] - while True: - cur_layer = next_layer.copy() - next_layer = [] - for p in cur_layer: - for n in neighbours(p): - if n in board and board[n] != "#" and n not in visited: - visited.add(n) - next_layer.append(n) - if len(next_layer) == 0: - break - steps += 1 - -if __name__ == "__main__": - input = open("../input/15", "r").readlines() - print(pt1(input)) - print(pt2(input)) - visualize(input) |
