Compare commits

...

4 commits

4 changed files with 430 additions and 0 deletions

73
2023/d21/ex1/ex1.py Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env python
import sys
from collections import defaultdict, deque
from typing import NamedTuple, Optional
class Point(NamedTuple):
x: int
y: int
GardenPoints = set[Point]
def solve(input: list[str]) -> int:
def parse(input: list[str]) -> tuple[GardenPoints, Point]:
start: Optional[Point] = None
points: GardenPoints = set()
for x, line in enumerate(input):
for y, c in enumerate(line):
if c == "#":
continue
if c == "S":
start = Point(x, y)
points.add(Point(x, y))
assert start is not None # Sanity check
return points, start
def explore(points: GardenPoints, start: Point) -> dict[Point, int]:
res: dict[Point, int] = {}
queue: deque[tuple[Point, int]] = deque([(start, 0)])
while queue:
point, dist = queue.popleft()
# If we already saw the point, then we saw it at a smaller distance
if point in res:
continue
# If it's not an actual garden point (rocks, out-of-bounds), don't log it
if point not in points:
continue
res[point] = dist
for dx, dy in (
(-1, 0),
(1, 0),
(0, -1),
(0, 1),
):
queue.append((Point(point.x + dx, point.y + dy), dist + 1))
return res
def reachable_in(distances: dict[Point, int], steps: int) -> set[Point]:
inverse_dist: dict[int, list[Point]] = defaultdict(list)
for p, dist in distances.items():
inverse_dist[dist].append(p)
return set(p for i in range(steps % 2, steps + 1, 2) for p in inverse_dist[i])
points, start = parse(input)
distances = explore(points, start)
return len(reachable_in(distances, 64))
def main() -> None:
input = sys.stdin.read().splitlines()
print(solve(input))
if __name__ == "__main__":
main()

131
2023/d21/ex1/input Normal file
View file

@ -0,0 +1,131 @@
...................................................................................................................................
....#.............#...............#.......#..........#..................##..........#.....#..................##...#...#..........#.
...............#......#........#.......#........#.........................#.....#........#........#...#....#....#.........#....##..
..#........#........#.##........#....#...#.....................................#................#.#...#..#....................#....
...................#.............#........#.....#........#.........................#.......#...#.........#...........#...........#.
...##.#....#...#.#..#....#.......##..#.....#..#..#......#.......#.........#.#.......#....#........#.....#.#...#................#...
............#....#.........#.#..............##..................................#.#.......#.#..........#...#..#.#......##..#.......
..................#...##............#.....#.....#.....#......................#..#.............................#....##..#...#.#.....
............#.............#.........#........................##..............#.#....#.............#..........#.....#...............
................#..#...##........#...#............#..................#.........#.....#..............#....#................#........
.#...#...#..#.#...#............#....#..#.#.........#............#.#.#..#..................#.##....#.............#..................
....#..#....#......#..#..##...#.#..#...##.........................#...................#..........#..#.......#...##.....#.....#.....
....................#..........................##................................#.....................#................#.....#.##.
..............#..............#..#..#.......#....#....................................#.........#..........#.#...............#.##...
........#......#.#.........#.......#..........#..................................................................#........#..#..#..
.................#.......##.......##......#..................#..#.......#....................#....#............#.......#.......#.#.
.....##.......#......#...#.#....#..#.................#.#....#.....#.............................#..#.........#.#.................#.
.......................#.....#...##...##..................................#....................##....##..........#..#..............
.#.......#....##.....#........#..............................#.....#....#.....................#........#..#..#.......#.#....#....#.
....#..#............#.........#...........................#.........##....#..#...................#..............#........#......##.
......##.................#..#.....................#...........................#.........................#...................#......
.....#...##.........#........#.##....###..................#........#..........................#.####................#.....#...#....
.#....#...#........#....#.............#................#.................##...#....#................#..#...#.....#............#....
....##.#.#.....#......#.......##.....#..........#........#..............#...#....#.................#.....#....#....................
.....#..............#.##..#.......#..........##..........................#.#.........#..........#....##....#.........#.#...........
.....#..#........#.#..........#...#.................#...........#.....#.........................#.#............#...................
.......#...........#..........#......................#........................##.....##............#........#..................##..
....#........................................#..#.....................#...#.#...#......................#...#....#................#.
....#.##......#........#.....................#.........#...................#...#....#.#..............###..................###......
..#...........#.....#....#..#.#............#...........#........#.....#.#................................#.......##....##..........
...##.###.....................#............#.....#..#.#..............##..#.##..#.....#...................#.#......#....#...........
.##....#............#....#.............#...#.#.............#..##.............#......................##.##..................#..#....
...#.....##.........#..##..............#..#........##..#.#................#...#.#.#....#..................#..............#.........
..........#....#.#.....#.................#...#............#.#......#...........#..........##..#...............#...#...##..#.#......
..............#.....................#....#..#.##...#.......#.#..#.....#..................#................#........................
......#.#.......#.....#...........##.................#......#........#.#........#..........#..##.........#...#.......#..#..........
........................#..........#..#..................#...................#..#..##...##..#...................#.............#....
...............#...#......................#....#...#..............##....#......#......#...#..#.....................................
......#...#...###..#..#...................#...#.#............#......#...##....#.........#..#.....#.........#.#........##...........
.#...#.........................##..##................#.....##.#...#........#.....#..#....##.........#..................#..#........
..#......#.........#..........##..#......##.#................................................#.......#.........................#.#.
......#....#..#.#..#.............#..............#.........#........#.....#.#..#......#.#.........................#..............#..
.........................................#........#..................#...##.......#..........#........#..........#..#..............
..#..........#............................#...#.....#....#..................#......................#.#..........#.##......#...#....
...........................................#.....#..#....#........#.....#........#......#...#...................................#..
..#..#...#.#..................#.#.............#..........#....#.....#......#......##.#..#...#.##....#....................#.....#...
..#..##..........................#........#....#..........#........#..........#..#.#..............#..#......................#.#....
....#...#.#.#..........#......................................#.......#...................##..#..#..................#.....#........
............................#............##.#..............#.......#.#...#....#.........#....#......#........................#.....
..#.........#...............#.......#....#..........#.....#.................#..#...##.#......................................#.....
.......#...#.................#..................#......#....#..##...#.........#.#.#..........#...##..#.#...................#.......
.........................#.............#....#...#.#.#....#.....#...............#........#.#...#..#..........#............#.........
.......##.............##............#..###..#.#..#..##....#...#......##..#...#........#....#..#..........#..#..#..........#........
..#..............#..##.......#...#........##.......................#..................#...........##........#.#..............#.....
.#...#.............................#.#.......#....................#.......#..........#...................#....#...##...............
..................####.#............###.....#.##..#...............#.............#..#..........#...............................#..#.
.....................#....#.......#......#......#......#..................#..#....#..........#....#..............#..#..............
.............#.#.##..#..#.....#.....##........##..#.#.........#......#..#.........##......#........#.........#...#...#.............
.#..........#..#.........#...#..##.........#........###......#....##...........#......#.#......................#.....#.............
..#.........##.#..#.#..........#.............................#.............##......#..#.............#.....#...#....#...............
.#......................#.....................###..#.#.....#..........#..#.#.#....#.......#..#.........#...........................
..........#......#....#..#....##..........#..........#.#...................#.................#....#.....#......#..........#........
.........................#.....#.....#........................#.........#.#...#............................#.....#.................
........#........#.........................##...............#.#.#......#......#......#..#.........#.....#.................#........
...............##..........#...........................#.....#....#.....#.#...................#.............#...............#......
.................................................................S.................................................................
.................##...#....#..........#..##..##..........#......#..#..............##...#.#......#......#......#..#.......#.........
..........#.........#.#...#..#....#.#.............#..#..#...........#.............#...........##.#...........#.......##............
........#............#.#..........#..##.#.#...............#.....#......#...#...#....#......#........#.............#.......#........
..........#...............#..#.................##.....#............#....###....#.............#................#...#................
.#..............#.....##.#....#...#..#.##.......................#.#....#.......#.#............#........#.....#..##...##............
.##.........#...................##.....#....#.......#.............##.......#...................#...........#.......#....#..........
............#..#...#.....#....#...........#.#......#.#..#.........#.#....#..................##............#........................
.............#..#...#....#......#......#......................#....#......###..........#..#.#..#...##....#..#......................
...#.........#..........#..#.........................##...........#......#............#..#.#.....##............#..#.#........#..#..
....#.#........##......................#.#.#.#..#.....#..#....##...#....##...#.#...#......#......................#.................
.....##..................#..........#.....##.....##..........#.#..#.......#.#...#.........#.......#..........#....#..........#.#...
...........................#..........#...#......#.#..#........#...#...............................#.#.#...#.....#..........#...##.
.....................#..##.##.....#......#.........#..##...#...............#.#.#........#..#...#...........#...#...................
..........#.........#..#.....#.......#.....###......#.....#.........#......#...............#.........#.........#...................
.......##..#..............#.........#.....#.......#...##.###...........#.#..........##.........................................#...
..#.....#..................#.#..........#..#..##....#...............#..............#.........##.........###.#...........#....##....
.#....#.....#.................#...#..........#.........#....#..............#.........##......#...#..........#........#.#.......#...
..............#.......................##.......##.......#..#.........#.....#....................................................#..
...#..#......#.............#....##..........#.#.......#...............#................###...#....#......#.........#.....#.....#...
....#..........#..........#..........#.....#..............#.......##......................#..#.#...............................#...
.#......#.....................................##.#..........................#.....#.#..#.#..........##.......................#...#.
......#........#.............#...........#.#............#.#.#...................#.##......#.#...................#....#..#..#.......
.#.........##.....#.............#...........#.......#.......#.....##..###.....#...........#.......................#.#..............
....##.........#.............................#.....##........#......#........#................#...#......................#.........
..................#...............##...............##.....#..#.#........#.....#.....#........#...#..#.........#.#.....#......#.#...
..................#.............##..#...............#....#.........##..#..........#......#....#.................##..#..#......#..#.
.........###.......#................#....##.....#...#...........#.............................#...#................#...............
...#......#...#...#...#...................#....#.#......#..#..#...#....#..#....................#..............#.................#..
......................#.............##..#....#...#..............#...................#..#.......#..............###................#.
..#........#.#............#..............#.......##......................#..............#..................#..#..#...........#.....
.#........#..............................#..........................................#..........#.......#.............#.#.......#...
.............#..#....#......#.......#.#.................................##...............................#....#......#.............
.#.#...#...#....#...#......#................#..#.......#..#.##..............#...........#....#.......#............#....#.........#.
...#.............#....#............................#........##.........##..........#..............................#.....#.......#..
....#......#....#......#...................#.........#.......##.......................#..................###........###.......#....
..........#...#......#........#..........#.........#.......#....#............#.....##......................#...........#..##..#.#..
.###.#.##......#.#........................#.#..#...................#.......#....#................##...#..#...#..#..#.###....#......
.....#.#......................................#.............#......#............................#..................................
..................#...............##.................#.........................#.................#.......#..##.#..##.....#..#......
...........#.........#.#...#....#.......................#.........#............#.#...#............##............#..................
.....#........#.............#..#..................#..#......#...#.#.......#.....................#..................................
..................#.#..............##..........#..........##....................................#.#............#.#.....#........#..
.....#.#.##....#..............#..........................#......#....#...#.....................................#...#..#.#.....#....
....#.#.........##.....................#...........................#......#.......#........#.#.#..#..#.......#....#..#......#...#..
............#.......#.............#......#...............#......#.##.....#..#......................#....#.....#...........#..##....
...#...#....#..#...##.......#.....#.....................##.....#..............#.............#...#....#..##.#....#........###..#....
.....#..............#....#.......#..........................#..........................#..##.....#...##................##..........
...#........#..#.#............##............#.........###....#.#.....#....#.............##................#.......#..##.......#.#..
...........#.........#..#...........#...................#......#.....#.....................#...........#.....#.....................
...#..#...##...............#..................#.............##......##...............#...#............#.........#..#...#.......#...
......#...........#............##.#.#...#...............#..#......##...........................#...#..#.#.......#.....#.........##.
...........#.#..#................#.......#......#............#..#.....#...............#....#.......#.#..#.#......#....#............
...#..............................................................#................#.....#.........................................
.................##.....................#.#....#..............#....................................#..............#.#..............
.............##.............#..##..................#..............#............#.................#........................#.#......
...........................#.....#..#..##.....##............#..#.......................#.....#..#.....#..#.....#........#....#.....
..........#.................#........#.......................................#.#...#..###...###.#...........#...#..................
..#....#.........#....#.........#....#.....#...................#............#....#.......#...#......#......#.#..........##..#......
...#........................#..#...........#...##..........................###................#.#.......#..................#.......
.......#.#............#.......#.....#.............................#.........#......#......................#........#...#.......#...
.#.#..#.........................#..........#......................................#...........#..#...............#......##.........
...#..............#......#.##....##.#...#..........##............................#.#.#........#.#........#....##.............#.....
....................#...............#..#........#...........................................##..........#.#.....#....#.#...#.......
.......................#........##..............#........#....................#.......#...#....#...........##........#....#.....#..
...................................................................................................................................

95
2023/d21/ex2/ex2.py Executable file
View file

@ -0,0 +1,95 @@
#!/usr/bin/env python
import sys
from typing import Iterator, NamedTuple, Optional
class Point(NamedTuple):
x: int
y: int
GardenPoints = set[Point]
GRID_SIZE = 131
MID_GRID = 65
STEPS = 26501365
def solve(input: list[str]) -> int:
def parse(input: list[str]) -> tuple[GardenPoints, Point]:
start: Optional[Point] = None
points: GardenPoints = set()
for x, line in enumerate(input):
for y, c in enumerate(line):
if c == "#":
continue
if c == "S":
start = Point(x, y)
points.add(Point(x, y))
assert start is not None # Sanity check
return points, start
def step(points: GardenPoints, positions: set[Point]) -> set[Point]:
res: set[Point] = set()
for p in positions:
for dx, dy in (
(-1, 0),
(1, 0),
(0, -1),
(0, 1),
):
x = p.x + dx
y = p.y + dy
# Check if the *wrapped* point is part of the garden
px = (x + GRID_SIZE) % GRID_SIZE
py = (y + GRID_SIZE) % GRID_SIZE
if Point(px, py) not in points:
continue
res.add(Point(x, y))
return res
def compute_quadratic(points: GardenPoints, start: Point) -> int:
def iterate() -> Iterator[int]:
positions = {start}
while True:
yield len(positions)
positions = step(points, positions)
values: list[tuple[int, int]] = []
for i, num in enumerate(iterate()):
if i % GRID_SIZE != MID_GRID:
continue
values.append((i, num))
if len(values) == 3:
break
# Lagrange interpolation
(x1, y1), (x2, y2), (x3, y3) = values
x = STEPS
return (
0
# Use integer division as it happens to work in our case
+ ((x - x2) * (x - x3)) * y1 // ((x1 - x2) * (x1 - x3))
+ ((x - x1) * (x - x3)) * y2 // ((x2 - x1) * (x2 - x3))
+ ((x - x1) * (x - x2)) * y3 // ((x3 - x1) * (x3 - x2))
)
assert len(input) == GRID_SIZE # Sanity check
assert len(input[0]) == GRID_SIZE # Sanity check
points, start = parse(input)
assert start == Point(MID_GRID, MID_GRID) # Sanity check
return compute_quadratic(points, start)
def main() -> None:
input = sys.stdin.read().splitlines()
print(solve(input))
if __name__ == "__main__":
main()

131
2023/d21/ex2/input Normal file
View file

@ -0,0 +1,131 @@
...................................................................................................................................
....#.............#...............#.......#..........#..................##..........#.....#..................##...#...#..........#.
...............#......#........#.......#........#.........................#.....#........#........#...#....#....#.........#....##..
..#........#........#.##........#....#...#.....................................#................#.#...#..#....................#....
...................#.............#........#.....#........#.........................#.......#...#.........#...........#...........#.
...##.#....#...#.#..#....#.......##..#.....#..#..#......#.......#.........#.#.......#....#........#.....#.#...#................#...
............#....#.........#.#..............##..................................#.#.......#.#..........#...#..#.#......##..#.......
..................#...##............#.....#.....#.....#......................#..#.............................#....##..#...#.#.....
............#.............#.........#........................##..............#.#....#.............#..........#.....#...............
................#..#...##........#...#............#..................#.........#.....#..............#....#................#........
.#...#...#..#.#...#............#....#..#.#.........#............#.#.#..#..................#.##....#.............#..................
....#..#....#......#..#..##...#.#..#...##.........................#...................#..........#..#.......#...##.....#.....#.....
....................#..........................##................................#.....................#................#.....#.##.
..............#..............#..#..#.......#....#....................................#.........#..........#.#...............#.##...
........#......#.#.........#.......#..........#..................................................................#........#..#..#..
.................#.......##.......##......#..................#..#.......#....................#....#............#.......#.......#.#.
.....##.......#......#...#.#....#..#.................#.#....#.....#.............................#..#.........#.#.................#.
.......................#.....#...##...##..................................#....................##....##..........#..#..............
.#.......#....##.....#........#..............................#.....#....#.....................#........#..#..#.......#.#....#....#.
....#..#............#.........#...........................#.........##....#..#...................#..............#........#......##.
......##.................#..#.....................#...........................#.........................#...................#......
.....#...##.........#........#.##....###..................#........#..........................#.####................#.....#...#....
.#....#...#........#....#.............#................#.................##...#....#................#..#...#.....#............#....
....##.#.#.....#......#.......##.....#..........#........#..............#...#....#.................#.....#....#....................
.....#..............#.##..#.......#..........##..........................#.#.........#..........#....##....#.........#.#...........
.....#..#........#.#..........#...#.................#...........#.....#.........................#.#............#...................
.......#...........#..........#......................#........................##.....##............#........#..................##..
....#........................................#..#.....................#...#.#...#......................#...#....#................#.
....#.##......#........#.....................#.........#...................#...#....#.#..............###..................###......
..#...........#.....#....#..#.#............#...........#........#.....#.#................................#.......##....##..........
...##.###.....................#............#.....#..#.#..............##..#.##..#.....#...................#.#......#....#...........
.##....#............#....#.............#...#.#.............#..##.............#......................##.##..................#..#....
...#.....##.........#..##..............#..#........##..#.#................#...#.#.#....#..................#..............#.........
..........#....#.#.....#.................#...#............#.#......#...........#..........##..#...............#...#...##..#.#......
..............#.....................#....#..#.##...#.......#.#..#.....#..................#................#........................
......#.#.......#.....#...........##.................#......#........#.#........#..........#..##.........#...#.......#..#..........
........................#..........#..#..................#...................#..#..##...##..#...................#.............#....
...............#...#......................#....#...#..............##....#......#......#...#..#.....................................
......#...#...###..#..#...................#...#.#............#......#...##....#.........#..#.....#.........#.#........##...........
.#...#.........................##..##................#.....##.#...#........#.....#..#....##.........#..................#..#........
..#......#.........#..........##..#......##.#................................................#.......#.........................#.#.
......#....#..#.#..#.............#..............#.........#........#.....#.#..#......#.#.........................#..............#..
.........................................#........#..................#...##.......#..........#........#..........#..#..............
..#..........#............................#...#.....#....#..................#......................#.#..........#.##......#...#....
...........................................#.....#..#....#........#.....#........#......#...#...................................#..
..#..#...#.#..................#.#.............#..........#....#.....#......#......##.#..#...#.##....#....................#.....#...
..#..##..........................#........#....#..........#........#..........#..#.#..............#..#......................#.#....
....#...#.#.#..........#......................................#.......#...................##..#..#..................#.....#........
............................#............##.#..............#.......#.#...#....#.........#....#......#........................#.....
..#.........#...............#.......#....#..........#.....#.................#..#...##.#......................................#.....
.......#...#.................#..................#......#....#..##...#.........#.#.#..........#...##..#.#...................#.......
.........................#.............#....#...#.#.#....#.....#...............#........#.#...#..#..........#............#.........
.......##.............##............#..###..#.#..#..##....#...#......##..#...#........#....#..#..........#..#..#..........#........
..#..............#..##.......#...#........##.......................#..................#...........##........#.#..............#.....
.#...#.............................#.#.......#....................#.......#..........#...................#....#...##...............
..................####.#............###.....#.##..#...............#.............#..#..........#...............................#..#.
.....................#....#.......#......#......#......#..................#..#....#..........#....#..............#..#..............
.............#.#.##..#..#.....#.....##........##..#.#.........#......#..#.........##......#........#.........#...#...#.............
.#..........#..#.........#...#..##.........#........###......#....##...........#......#.#......................#.....#.............
..#.........##.#..#.#..........#.............................#.............##......#..#.............#.....#...#....#...............
.#......................#.....................###..#.#.....#..........#..#.#.#....#.......#..#.........#...........................
..........#......#....#..#....##..........#..........#.#...................#.................#....#.....#......#..........#........
.........................#.....#.....#........................#.........#.#...#............................#.....#.................
........#........#.........................##...............#.#.#......#......#......#..#.........#.....#.................#........
...............##..........#...........................#.....#....#.....#.#...................#.............#...............#......
.................................................................S.................................................................
.................##...#....#..........#..##..##..........#......#..#..............##...#.#......#......#......#..#.......#.........
..........#.........#.#...#..#....#.#.............#..#..#...........#.............#...........##.#...........#.......##............
........#............#.#..........#..##.#.#...............#.....#......#...#...#....#......#........#.............#.......#........
..........#...............#..#.................##.....#............#....###....#.............#................#...#................
.#..............#.....##.#....#...#..#.##.......................#.#....#.......#.#............#........#.....#..##...##............
.##.........#...................##.....#....#.......#.............##.......#...................#...........#.......#....#..........
............#..#...#.....#....#...........#.#......#.#..#.........#.#....#..................##............#........................
.............#..#...#....#......#......#......................#....#......###..........#..#.#..#...##....#..#......................
...#.........#..........#..#.........................##...........#......#............#..#.#.....##............#..#.#........#..#..
....#.#........##......................#.#.#.#..#.....#..#....##...#....##...#.#...#......#......................#.................
.....##..................#..........#.....##.....##..........#.#..#.......#.#...#.........#.......#..........#....#..........#.#...
...........................#..........#...#......#.#..#........#...#...............................#.#.#...#.....#..........#...##.
.....................#..##.##.....#......#.........#..##...#...............#.#.#........#..#...#...........#...#...................
..........#.........#..#.....#.......#.....###......#.....#.........#......#...............#.........#.........#...................
.......##..#..............#.........#.....#.......#...##.###...........#.#..........##.........................................#...
..#.....#..................#.#..........#..#..##....#...............#..............#.........##.........###.#...........#....##....
.#....#.....#.................#...#..........#.........#....#..............#.........##......#...#..........#........#.#.......#...
..............#.......................##.......##.......#..#.........#.....#....................................................#..
...#..#......#.............#....##..........#.#.......#...............#................###...#....#......#.........#.....#.....#...
....#..........#..........#..........#.....#..............#.......##......................#..#.#...............................#...
.#......#.....................................##.#..........................#.....#.#..#.#..........##.......................#...#.
......#........#.............#...........#.#............#.#.#...................#.##......#.#...................#....#..#..#.......
.#.........##.....#.............#...........#.......#.......#.....##..###.....#...........#.......................#.#..............
....##.........#.............................#.....##........#......#........#................#...#......................#.........
..................#...............##...............##.....#..#.#........#.....#.....#........#...#..#.........#.#.....#......#.#...
..................#.............##..#...............#....#.........##..#..........#......#....#.................##..#..#......#..#.
.........###.......#................#....##.....#...#...........#.............................#...#................#...............
...#......#...#...#...#...................#....#.#......#..#..#...#....#..#....................#..............#.................#..
......................#.............##..#....#...#..............#...................#..#.......#..............###................#.
..#........#.#............#..............#.......##......................#..............#..................#..#..#...........#.....
.#........#..............................#..........................................#..........#.......#.............#.#.......#...
.............#..#....#......#.......#.#.................................##...............................#....#......#.............
.#.#...#...#....#...#......#................#..#.......#..#.##..............#...........#....#.......#............#....#.........#.
...#.............#....#............................#........##.........##..........#..............................#.....#.......#..
....#......#....#......#...................#.........#.......##.......................#..................###........###.......#....
..........#...#......#........#..........#.........#.......#....#............#.....##......................#...........#..##..#.#..
.###.#.##......#.#........................#.#..#...................#.......#....#................##...#..#...#..#..#.###....#......
.....#.#......................................#.............#......#............................#..................................
..................#...............##.................#.........................#.................#.......#..##.#..##.....#..#......
...........#.........#.#...#....#.......................#.........#............#.#...#............##............#..................
.....#........#.............#..#..................#..#......#...#.#.......#.....................#..................................
..................#.#..............##..........#..........##....................................#.#............#.#.....#........#..
.....#.#.##....#..............#..........................#......#....#...#.....................................#...#..#.#.....#....
....#.#.........##.....................#...........................#......#.......#........#.#.#..#..#.......#....#..#......#...#..
............#.......#.............#......#...............#......#.##.....#..#......................#....#.....#...........#..##....
...#...#....#..#...##.......#.....#.....................##.....#..............#.............#...#....#..##.#....#........###..#....
.....#..............#....#.......#..........................#..........................#..##.....#...##................##..........
...#........#..#.#............##............#.........###....#.#.....#....#.............##................#.......#..##.......#.#..
...........#.........#..#...........#...................#......#.....#.....................#...........#.....#.....................
...#..#...##...............#..................#.............##......##...............#...#............#.........#..#...#.......#...
......#...........#............##.#.#...#...............#..#......##...........................#...#..#.#.......#.....#.........##.
...........#.#..#................#.......#......#............#..#.....#...............#....#.......#.#..#.#......#....#............
...#..............................................................#................#.....#.........................................
.................##.....................#.#....#..............#....................................#..............#.#..............
.............##.............#..##..................#..............#............#.................#........................#.#......
...........................#.....#..#..##.....##............#..#.......................#.....#..#.....#..#.....#........#....#.....
..........#.................#........#.......................................#.#...#..###...###.#...........#...#..................
..#....#.........#....#.........#....#.....#...................#............#....#.......#...#......#......#.#..........##..#......
...#........................#..#...........#...##..........................###................#.#.......#..................#.......
.......#.#............#.......#.....#.............................#.........#......#......................#........#...#.......#...
.#.#..#.........................#..........#......................................#...........#..#...............#......##.........
...#..............#......#.##....##.#...#..........##............................#.#.#........#.#........#....##.............#.....
....................#...............#..#........#...........................................##..........#.#.....#....#.#...#.......
.......................#........##..............#........#....................#.......#...#....#...........##........#....#.....#..
...................................................................................................................................