1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #!/usr/bin/python3
- import sys
- import re
- from dataclasses import dataclass
- import os
- @dataclass(frozen=True)
- class Pos:
- x: int
- y: int
- def walk(self, dpos, steps):
- return Pos(self.x + dpos.x * steps, self.y + dpos.y * steps)
-
- def add_x(self, x):
- return Pos(self.x + x, self.y)
- def add_y(self, y):
- return Pos(self.x, self.y + y)
- def minimize(self, pos):
- return Pos(min(self.x, pos.x), min(self.y, pos.y))
- def maximize(self, pos):
- return Pos(max(self.x, pos.x), max(self.y, pos.y))
- def grid_str(points, upperleft, lowerright):
- chars = [['#' if Pos(x, y) in points else ' ' for x in range(upperleft.x, lowerright.x + 1)] for y in range(upperleft.y, lowerright.y + 1)]
- return '\n'.join([''.join(line) for line in chars])
- def generate_directions(pos):
- yield pos.add_x(-1)
- yield pos.add_x(1)
- yield pos.add_y(-1)
- yield pos.add_y(1)
- def flood(boundary, upperleft, lowerright):
- count = 0
- start = Pos((upperleft.x + lowerright.x) // 2, (upperleft.y + lowerright.y) // 2)
- last = set()
- seen = set([start])
- considered = boundary.copy()
- #n = 0
- while last != seen:
- last = seen.copy()
- for p in last:
- for np in generate_directions(p):
- if np in considered:
- continue
- seen.add(np)
- considered.add(p)
- seen.remove(p)
- #n += 1
- #if n % 32 == 0:
- #n = 0
- #os.system('clear')
- #print(grid_str(considered, upperleft, lowerright))
- print(len(considered))
- def part12(swapped=False):
- print('part 1')
- corners = set()
- boundary = set()
- pos = Pos(0, 0)
- upperleft = Pos(0, 0)
- lowerright = Pos(0, 0)
- directions = { 'U': Pos(0, -1) , 'R': Pos(1, 0), 'D': Pos(0, 1), 'L': Pos(-1, 0) }
- for line in map(str.strip, sys.stdin):
- found = re.findall(r'([UDRL]) ([0-9]+) \(#([0-9a-f]+)\)', line)[0]
- if swapped:
- direction = {'0': 'R', '1': 'D', '2': 'L', '3': 'U'}[found[2][-1]]
- steps = int(found[2][:-1], 16)
- else:
- direction, steps = found[0], int(found[1])
- print(direction, steps)
- last = pos
- pos = pos.walk(directions[direction], steps)
- upperleft = upperleft.minimize(pos)
- lowerright = lowerright.maximize(pos)
- for x in range(min(last.x, pos.x), max(last.x, pos.x) + 1):
- for y in range(min(last.y, pos.y), max(last.y, pos.y) + 1):
- boundary.add(Pos(x, y))
- corners.add(pos)
- print(grid_str(boundary, upperleft, lowerright))
- flood(boundary, upperleft, lowerright)
- if sys.argv[1] in '1':
- part12()
- else:
- part12(swapped=True)
|