|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- def render(graph, default='.'):
- xmin, *_, xmax = sorted(int(p.real) for p in graph)
- ymin, *_, ymax = sorted(int(p.imag) for p in graph)
- out = ''
- for y in range(ymin, ymax + 1):
- for x in range(xmin, xmax + 1):
- out += graph.get(complex(x, y), default)
- out += '\n'
- return out
-
-
- def connected_components(graph):
- groups = []
- while graph:
- seen = set()
- edge = {graph.pop()}
- while edge:
- seen |= edge
- edge = {pp + ss for pp in edge for ss in [1, -1, 1j, -1j] if pp + ss in graph if pp + ss not in seen}
- groups.append(seen)
- graph -= seen
- return groups
-
-
- def get_solid(walls):
- xmin, *_, xmax = sorted(int(p.real) for p in walls)
- ymin, *_, ymax = sorted(int(p.imag) for p in walls)
-
- mesh = {complex(x, y) for x in range(xmin, xmax + 1) for y in range(ymin, ymax + 1)}
- void = mesh - walls
- groups = connected_components(void)
- border = lambda p: p.real in {xmin, xmax} or p.imag in {ymin, ymax}
- inside = {p for g in groups if not any(border(p) for p in g) for p in g}
- solid = inside | walls
- return solid
-
-
- def solve1():
- pos = 0
- walls = {pos}
- for line in text.splitlines():
- d, n, _ = line.split()
- dirx = 1j ** 'RDLU'.index(d)
- goal = pos + dirx * int(n)
- while pos != goal:
- pos += dirx
- walls.add(pos)
- solid = get_solid(walls)
- print(len(solid))
-
-
- def solve2():
- points = {0}
- pos = 0
- for line in text.splitlines():
- _, _, rest = line.split()
- n, d = int(rest[1:-1][1:][:5], 16), 'RDLU'[int(rest[-2])]
- dirx = 1j ** 'RDLU'.index(d)
- pos += dirx * int(n)
- points.add(pos)
-
- b2s = {
- complex(bx, by) + dx + dy: 3 * complex(sx, sy) + dx + dy
- for sx, bx in enumerate(sorted({p.real for p in points}))
- for sy, by in enumerate(sorted({p.imag for p in points}))
- for dx in [-1, 0, 1] for dy in [-1j, 0, 1j]
- }
- s2b = {v: k for k, v in b2s.items()}
-
- pos, smallpos = 0, b2s[0]
- walls = {smallpos}
- for line in text.splitlines():
- d, n, rest = line.split()
- n, d = int(rest[1:-1][1:][:5], 16), 'RDLU'[int(rest[-2])]
- dirx = 1j ** 'RDLU'.index(d)
- pos += dirx * int(n)
- goal = b2s[pos]
- while smallpos != goal:
- smallpos += dirx
- walls.add(smallpos)
-
- solid = get_solid(walls)
-
- out = 0
- for smallpos in solid:
- c1, c2 = s2b[smallpos], s2b[smallpos + 1 + 1j]
- w, h = (c2 - c1).real, (c2 - c1).imag
- out += int(w * h)
- print(out)
-
-
- text = open(0).read()
- solve1()
- solve2()
|