Compare commits
4 commits
1c57181989
...
d1194e8c5f
Author | SHA1 | Date | |
---|---|---|---|
Bruno BELANYI | d1194e8c5f | ||
Bruno BELANYI | 7759412af3 | ||
Bruno BELANYI | 4211451deb | ||
Bruno BELANYI | 1562f97efc |
147
2022/d24/ex1/ex1.py
Executable file
147
2022/d24/ex1/ex1.py
Executable file
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import dataclasses
|
||||
import enum
|
||||
import sys
|
||||
from collections import defaultdict, deque
|
||||
from collections.abc import Iterator
|
||||
from typing import NamedTuple
|
||||
|
||||
|
||||
class Point(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, Point):
|
||||
return NotImplemented
|
||||
return Point(self.x + other.x, self.y + other.y)
|
||||
|
||||
def __sub__(self, other):
|
||||
if not isinstance(other, Point):
|
||||
return NotImplemented
|
||||
return Point(self.x - other.x, self.y - other.y)
|
||||
|
||||
|
||||
class Direction(str, enum.Enum):
|
||||
UP = "^"
|
||||
DOWN = "v"
|
||||
LEFT = "<"
|
||||
RIGHT = ">"
|
||||
|
||||
def to_delta(self) -> Point:
|
||||
match self:
|
||||
case Direction.UP:
|
||||
return Point(-1, 0)
|
||||
case Direction.DOWN:
|
||||
return Point(1, 0)
|
||||
case Direction.LEFT:
|
||||
return Point(0, -1)
|
||||
case Direction.RIGHT:
|
||||
return Point(0, 1)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ValleyMap:
|
||||
start: Point
|
||||
goal: Point
|
||||
valley_corners: tuple[Point, Point]
|
||||
tornadoes: dict[Point, Direction]
|
||||
|
||||
@classmethod
|
||||
def from_input(cls, input: list[str]) -> "ValleyMap":
|
||||
tornadoes: dict[Point, Direction] = {}
|
||||
for x, line in enumerate(input, start=1):
|
||||
for y, c in enumerate(line, start=1):
|
||||
if c in ("#", "."):
|
||||
continue
|
||||
tornadoes[Point(x, y)] = Direction(c)
|
||||
return cls(
|
||||
# Start position is always above the upper left corner of valley
|
||||
start=Point(1, 2),
|
||||
# Goal position is always under the lower left corner of valley
|
||||
goal=Point(len(input), len(input[0]) - 1),
|
||||
# Valley is surrounded by walls, except entrance and exit
|
||||
valley_corners=(Point(2, 2), Point(len(input) - 1, len(input[0]) - 1)),
|
||||
tornadoes=tornadoes,
|
||||
)
|
||||
|
||||
def _is_in_valley(self, p: Point) -> bool:
|
||||
# Valley also includes start/end
|
||||
if p in (self.start, self.goal):
|
||||
return True
|
||||
# Otherwise, just do a bounds check for inside the walls
|
||||
((minx, miny), (maxx, maxy)) = self.valley_corners
|
||||
return (minx <= p.x <= maxx) and (miny <= p.y <= maxy)
|
||||
|
||||
def _wrap_tornado(self, p: Point) -> Point:
|
||||
if self._is_in_valley(p):
|
||||
return p
|
||||
x, y = p
|
||||
h = self.valley_corners[1].x - self.valley_corners[0].x + 1
|
||||
w = self.valley_corners[1].y - self.valley_corners[0].y + 1
|
||||
if x == 1:
|
||||
x += h
|
||||
if y == 1:
|
||||
y += w
|
||||
if x > self.valley_corners[1].x:
|
||||
x -= h
|
||||
if y > self.valley_corners[1].y:
|
||||
y -= w
|
||||
return Point(x, y)
|
||||
|
||||
def navigate(self) -> int:
|
||||
TornadoesMap = dict[Point, list[Direction]]
|
||||
|
||||
def move_tornadoes(map: TornadoesMap) -> dict[Point, list[Direction]]:
|
||||
res: dict[Point, list[Direction]] = defaultdict(list)
|
||||
for p, tornadoes in map.items():
|
||||
for t in tornadoes:
|
||||
new_pos = self._wrap_tornado(p + t.to_delta())
|
||||
res[new_pos].append(t)
|
||||
return dict(res)
|
||||
|
||||
def moves(p: Point) -> Iterator[Point]:
|
||||
yield p
|
||||
for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
|
||||
yield p + Point(dx, dy)
|
||||
|
||||
# Do a BFS to find the fastest route
|
||||
queue: deque[tuple[int, Point]] = deque([(0, self.start)])
|
||||
seen: set[tuple[int, Point]] = set()
|
||||
tornado_history = [{p: [t] for p, t in self.tornadoes.items()}]
|
||||
while queue:
|
||||
dist, pos = queue.popleft()
|
||||
# If goal found, return total distance
|
||||
if pos == self.goal:
|
||||
return dist
|
||||
# Check that we don't do redundant work
|
||||
if (dist, pos) in seen:
|
||||
continue
|
||||
seen.add((dist, pos))
|
||||
if len(tornado_history) <= (dist + 1):
|
||||
tornado_history.append(move_tornadoes(tornado_history[-1]))
|
||||
for new_pos in moves(pos):
|
||||
# Can't move into the walls, but can move in start/end
|
||||
if not self._is_in_valley(new_pos):
|
||||
continue
|
||||
# Can't occupy same space as tornadoes
|
||||
if new_pos in tornado_history[dist + 1]:
|
||||
continue
|
||||
# Enqueue this move to the search space
|
||||
queue.append((dist + 1, new_pos))
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def solve(input: list[str]) -> int:
|
||||
valley = ValleyMap.from_input(input)
|
||||
return valley.navigate()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = sys.stdin.read().splitlines()
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
22
2022/d24/ex1/input
Normal file
22
2022/d24/ex1/input
Normal file
|
@ -0,0 +1,22 @@
|
|||
#.######################################################################################################################################################
|
||||
#<v^>^>^^<><^>^^v>vv^v^>>^<>^<v<>v^>>v>v><^..><v<^v<<^v>v>>>>^<v^>>>.v>.v><<v><.^>>^^^>v>>^.<v>>vv<<.<<v<<vv^<^>^v>^v<>^^.^.<<<v^>>^<^>.>vvv><^<^>v.^<>#
|
||||
#<..v<<^^.^^v<<>>v<vv.><v<<<>>>.<>>^vv^^v>v^>><v<.<<v.v^^>>v^vv<<><>>v.>.v>.<..v>^^>^<<vv>><>vv>>v>.><.<<vv<v^..v<v<v^v>v^vv<v<v^.^<v<.<<><>vvvvv^<^v>.#
|
||||
#<>>^<v>v^v>v>.^v<>v<v^<<<.^^<.>vv>>^<<^>>v<v.>^^^.<<<.>>v.>.v^<v><v>.>>>^><>v>>v^<.v^<.vv^>^v<><>>v^^<^>..<v><<^<<<^<v><^>^<>v>vvv>>^<<>><><<^^.<<v>v>#
|
||||
#>.<<<^..>><>v>^vv>vv<v..^>^^>>.><^<v.>>><^.^<>^v>.<^<>>>^>>^><^><^.^>.><><><^>^>>^>>>^<.>>^<^>vv<^v^><vv^v>.>^>>vv.^<>>^>>>><>.^.>v<.^<>v^>v>^^>>v<><>#
|
||||
#>>v<^v^<^^><>><>.>v^v>^v.>v^.>>.><><<>^><<>^>^v>v^^^>>^v<<<>v<vv>v>>v<^^^<<<<v^vv><>v<^>>.<v.^^>^v<v<v.v..v<^^>>><.v^<.>>vv>v><><.^^^v><.<<v^>^>>><v><#
|
||||
#>>vv<^vv<<v<^v^.><>^<v<>v<^v.>>v<><>.>^.^....<<^<.<v>><v>^^^<><>.>^<<v^<>>>^^><v><>>v^v<v<v^<.^<v>v^<>v^<vv^.<^v>^^^v.<><^><^v<<.v>>><>>><.v>v>>^.^>^>#
|
||||
#<v<>>^v>v^vv^.^<<<^><>v^<.>>^^^<^<^>.>>^<<.^>><<<v^v>.>^^.vv>.v<v^>v><^^.<<<v^>v..<^<.vvv<.<v..<.>.v>.>>^v<^^<^v^>^.<<^^.^^<><v^^v<^^^v>v<<<<v<<>v>><>#
|
||||
#<^>>^>><<>v.v>.vvv><^><v<^v<>v..<<<>>><<vv>^v><^>..<^^v>.<<<v><v^^vv^^>>.v..^<.^v<v>v.><vv>^><>vv><<>v^>v>><^^>^>><^>.>^^<<><><^.>^v<>v^.>v><>>.v^..v>#
|
||||
#<.<<<^><><^<<^>><..>^<<<>^.<>>v..v^^<<<.><.^.<^>^vvv^^^^>v>^<v>>>>>v<><>v.<>>^.<>v^<.^vv>v^<v>.><v<^.><<^vv<>><>v><^v>>^^^.v^v>v>^v^>.v<<^>.^v<v>^>vv<#
|
||||
#<<>^^.^>v<vvvv<<^v<v<<<v>.<>>^>^.<<^>^><<>v^.><<<.^^^<<^><<^^>.>vv<v<>>^>^^v<.^>.<v<>^>^<^>^.<>^v.^^^.v><v>^.^v^<<<><<>v.>>>>^<v>..v>^^v<v<^>v<v.>^v>>#
|
||||
#<^.<^^><>^^^<<>>^>.^^^<^<^<^^<^v.^^v>^v<>.^v^^<<..v<^<>>^<..<^.>><v<>^>.^v.>>v^.v..v.<<vv^>^vvv^v<vv<^.^><><><<^v^v.^^<<>^vv>^^>v>^v<<^>^<vvv.><^.^<v>#
|
||||
#<^^v^v>^<^><>v><.><v>^>^<vv<>..v^>^v^>^><>v<^v^<<v<<<<v<v..^^^<><v>v>^vv<^v.<><>vv>>>>v<>^vv<^v<>^^.v>>^^<<.<^<v<>>^>>vv>vv^<v^^>>^<v<.v<v>v<<>.>^>^v>#
|
||||
#<<>>>.<<>^>>v>^<^v>><<^v<><<.^<^<>>><^v>>v>^<^vv.<^^^.vv^<<<>^^>v>^v.>^^v>v.<>vvv><<v>v>^v.<v^<>^>vv<><vv<v^<><vv.>^>.>.v^v.v^vv^<.<>.>vv>^>v<v<v>^<.<#
|
||||
#>^<^<v<^^<^^v><<.<<..>>.>^^v>>v>^^>^^>>>v>v^<v^><>v>><v^<v>^>vvv>><>>vv>.>^.^<>.><v.>^.v<><v<^v><v.v<v<..^>^^<^v^>>.>v.v<><<<v><>^<<^>^>^>^.vv..<>v<^>#
|
||||
#..v<<^v^^>^>^<^<vvv>v<v^^v^.<<vvv.v.v^v>^v^^v>><^><<^v.<vv<><.vv^v<<>^v<<^v^v^^.>^>v<^^v...>>vv.<^v>v^<<^<vv>v^>v<^>v<vv>^<>.>v^^^^.^<>^^.^><.<.>>.><.#
|
||||
#<vv>v^<v^.vv<<.>v<<^v^>>^vv.v>>v>.vv^>>vv.>v>>>^.>>><.^.^<><>^vv<^<>><<vv<<v>^v^>>.<v^<v^<^^^<><>v<>v<....^^><.<^^>v^v>v<v<.><<>>^<>.v.<.vv<.>^.^v^>.>#
|
||||
#<<v<^vv^>v>>^>.>^^^<.>>^<><>>.>^v^<.v^^.^<<^>^.^v^^v<v<><>>.>.<>.^.v>.<v>^><^>v>v<>.^v<><.<<.><<^v<><><^>v^...v<<^^<^>v>^^vv^^vvv>^>v>>.>>v^^.vv>^<v<>#
|
||||
#>v<>^v><>^>>><<^.^v<<v^>v<>>>.^v><^v<<>v<^^.<.><><v>^<><.v<v<<^^^>>><^>^>>.<>vvvv.^^v<<>^<>>><<v^v><v>>>^v.<^>.^>><v><<><vv.v<vv<v^^>v<.<^<^>v^^>v^.><#
|
||||
#><v>vv^<^.<^>v^v^<><><vvv^v>v<>>v^<>^>>>^v^<v>>v<<^.^<v^vvv^^<><vvv.<vv^.>>v^<v.^vv><vv<>v^<^<^^>^^^vv^.<><>><^v.<^<.<>.>^<^<^<>v<^.<v<v<v>^vv><.v<^>>#
|
||||
#>v^.v>^v<>>v^>>>^^^^>.v<<^>^v>.^^>^>v^<^v^^<^^v>v>.v^<v>^v><^^.><^^>>v>v^v<v.<^>><>vv><v^v^><>^vvv>>v>>^v^^<^>>v^<^vv^<^^^^vv<><vv<.v^><v>^^>v^v<><<<<#
|
||||
######################################################################################################################################################.#
|
164
2022/d24/ex2/ex2.py
Executable file
164
2022/d24/ex2/ex2.py
Executable file
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import dataclasses
|
||||
import enum
|
||||
import sys
|
||||
from collections import defaultdict, deque
|
||||
from collections.abc import Iterator
|
||||
from typing import NamedTuple
|
||||
|
||||
|
||||
class Point(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, Point):
|
||||
return NotImplemented
|
||||
return Point(self.x + other.x, self.y + other.y)
|
||||
|
||||
def __sub__(self, other):
|
||||
if not isinstance(other, Point):
|
||||
return NotImplemented
|
||||
return Point(self.x - other.x, self.y - other.y)
|
||||
|
||||
|
||||
class Direction(str, enum.Enum):
|
||||
UP = "^"
|
||||
DOWN = "v"
|
||||
LEFT = "<"
|
||||
RIGHT = ">"
|
||||
|
||||
def to_delta(self) -> Point:
|
||||
match self:
|
||||
case Direction.UP:
|
||||
return Point(-1, 0)
|
||||
case Direction.DOWN:
|
||||
return Point(1, 0)
|
||||
case Direction.LEFT:
|
||||
return Point(0, -1)
|
||||
case Direction.RIGHT:
|
||||
return Point(0, 1)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ValleyMap:
|
||||
start: Point
|
||||
goal: Point
|
||||
valley_corners: tuple[Point, Point]
|
||||
tornadoes: dict[Point, Direction]
|
||||
|
||||
@classmethod
|
||||
def from_input(cls, input: list[str]) -> "ValleyMap":
|
||||
tornadoes: dict[Point, Direction] = {}
|
||||
for x, line in enumerate(input, start=1):
|
||||
for y, c in enumerate(line, start=1):
|
||||
if c in ("#", "."):
|
||||
continue
|
||||
tornadoes[Point(x, y)] = Direction(c)
|
||||
return cls(
|
||||
# Start position is always above the upper left corner of valley
|
||||
start=Point(1, 2),
|
||||
# Goal position is always under the lower left corner of valley
|
||||
goal=Point(len(input), len(input[0]) - 1),
|
||||
# Valley is surrounded by walls, except entrance and exit
|
||||
valley_corners=(Point(2, 2), Point(len(input) - 1, len(input[0]) - 1)),
|
||||
tornadoes=tornadoes,
|
||||
)
|
||||
|
||||
def _is_in_valley(self, p: Point) -> bool:
|
||||
# Valley also includes start/end
|
||||
if p in (self.start, self.goal):
|
||||
return True
|
||||
# Otherwise, just do a bounds check for inside the walls
|
||||
((minx, miny), (maxx, maxy)) = self.valley_corners
|
||||
return (minx <= p.x <= maxx) and (miny <= p.y <= maxy)
|
||||
|
||||
def _wrap_tornado(self, p: Point) -> Point:
|
||||
if self._is_in_valley(p):
|
||||
return p
|
||||
x, y = p
|
||||
h = self.valley_corners[1].x - self.valley_corners[0].x + 1
|
||||
w = self.valley_corners[1].y - self.valley_corners[0].y + 1
|
||||
if x == 1:
|
||||
x += h
|
||||
if y == 1:
|
||||
y += w
|
||||
if x > self.valley_corners[1].x:
|
||||
x -= h
|
||||
if y > self.valley_corners[1].y:
|
||||
y -= w
|
||||
return Point(x, y)
|
||||
|
||||
def navigate(self) -> int:
|
||||
TornadoesMap = dict[Point, list[Direction]]
|
||||
|
||||
def move_tornadoes(map: TornadoesMap) -> dict[Point, list[Direction]]:
|
||||
res: dict[Point, list[Direction]] = defaultdict(list)
|
||||
for p, tornadoes in map.items():
|
||||
for t in tornadoes:
|
||||
new_pos = self._wrap_tornado(p + t.to_delta())
|
||||
res[new_pos].append(t)
|
||||
return dict(res)
|
||||
|
||||
def moves(p: Point) -> Iterator[Point]:
|
||||
yield p
|
||||
for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
|
||||
yield p + Point(dx, dy)
|
||||
|
||||
def bfs(
|
||||
start: Point, goal: Point, tornadoes: TornadoesMap
|
||||
) -> tuple[int, TornadoesMap]:
|
||||
# Do a BFS to find the fastest route
|
||||
queue: deque[tuple[int, Point]] = deque([(0, start)])
|
||||
seen: set[tuple[int, Point]] = set()
|
||||
tornado_history = [tornadoes]
|
||||
while queue:
|
||||
dist, pos = queue.popleft()
|
||||
# If goal found, return total distance
|
||||
if pos == goal:
|
||||
return dist, tornado_history[dist]
|
||||
# Check that we don't do redundant work
|
||||
if (dist, pos) in seen:
|
||||
continue
|
||||
seen.add((dist, pos))
|
||||
if len(tornado_history) <= (dist + 1):
|
||||
tornado_history.append(move_tornadoes(tornado_history[-1]))
|
||||
for new_pos in moves(pos):
|
||||
# Can't move into the walls, but can move in start/end
|
||||
if not self._is_in_valley(new_pos):
|
||||
continue
|
||||
# Can't occupy same space as tornadoes
|
||||
if new_pos in tornado_history[dist + 1]:
|
||||
continue
|
||||
# Enqueue this move to the search space
|
||||
queue.append((dist + 1, new_pos))
|
||||
assert False # Sanity check
|
||||
|
||||
tornadoes = {p: [t] for p, t in self.tornadoes.items()}
|
||||
total = 0
|
||||
for start, end in (
|
||||
# First travel
|
||||
(self.start, self.goal),
|
||||
# Back for snacks
|
||||
(self.goal, self.start),
|
||||
# Second travel
|
||||
(self.start, self.goal),
|
||||
):
|
||||
dist, tornadoes = bfs(start, end, tornadoes)
|
||||
total += dist
|
||||
return total
|
||||
|
||||
|
||||
def solve(input: list[str]) -> int:
|
||||
valley = ValleyMap.from_input(input)
|
||||
return valley.navigate()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = sys.stdin.read().splitlines()
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
22
2022/d24/ex2/input
Normal file
22
2022/d24/ex2/input
Normal file
|
@ -0,0 +1,22 @@
|
|||
#.######################################################################################################################################################
|
||||
#<v^>^>^^<><^>^^v>vv^v^>>^<>^<v<>v^>>v>v><^..><v<^v<<^v>v>>>>^<v^>>>.v>.v><<v><.^>>^^^>v>>^.<v>>vv<<.<<v<<vv^<^>^v>^v<>^^.^.<<<v^>>^<^>.>vvv><^<^>v.^<>#
|
||||
#<..v<<^^.^^v<<>>v<vv.><v<<<>>>.<>>^vv^^v>v^>><v<.<<v.v^^>>v^vv<<><>>v.>.v>.<..v>^^>^<<vv>><>vv>>v>.><.<<vv<v^..v<v<v^v>v^vv<v<v^.^<v<.<<><>vvvvv^<^v>.#
|
||||
#<>>^<v>v^v>v>.^v<>v<v^<<<.^^<.>vv>>^<<^>>v<v.>^^^.<<<.>>v.>.v^<v><v>.>>>^><>v>>v^<.v^<.vv^>^v<><>>v^^<^>..<v><<^<<<^<v><^>^<>v>vvv>>^<<>><><<^^.<<v>v>#
|
||||
#>.<<<^..>><>v>^vv>vv<v..^>^^>>.><^<v.>>><^.^<>^v>.<^<>>>^>>^><^><^.^>.><><><^>^>>^>>>^<.>>^<^>vv<^v^><vv^v>.>^>>vv.^<>>^>>>><>.^.>v<.^<>v^>v>^^>>v<><>#
|
||||
#>>v<^v^<^^><>><>.>v^v>^v.>v^.>>.><><<>^><<>^>^v>v^^^>>^v<<<>v<vv>v>>v<^^^<<<<v^vv><>v<^>>.<v.^^>^v<v<v.v..v<^^>>><.v^<.>>vv>v><><.^^^v><.<<v^>^>>><v><#
|
||||
#>>vv<^vv<<v<^v^.><>^<v<>v<^v.>>v<><>.>^.^....<<^<.<v>><v>^^^<><>.>^<<v^<>>>^^><v><>>v^v<v<v^<.^<v>v^<>v^<vv^.<^v>^^^v.<><^><^v<<.v>>><>>><.v>v>>^.^>^>#
|
||||
#<v<>>^v>v^vv^.^<<<^><>v^<.>>^^^<^<^>.>>^<<.^>><<<v^v>.>^^.vv>.v<v^>v><^^.<<<v^>v..<^<.vvv<.<v..<.>.v>.>>^v<^^<^v^>^.<<^^.^^<><v^^v<^^^v>v<<<<v<<>v>><>#
|
||||
#<^>>^>><<>v.v>.vvv><^><v<^v<>v..<<<>>><<vv>^v><^>..<^^v>.<<<v><v^^vv^^>>.v..^<.^v<v>v.><vv>^><>vv><<>v^>v>><^^>^>><^>.>^^<<><><^.>^v<>v^.>v><>>.v^..v>#
|
||||
#<.<<<^><><^<<^>><..>^<<<>^.<>>v..v^^<<<.><.^.<^>^vvv^^^^>v>^<v>>>>>v<><>v.<>>^.<>v^<.^vv>v^<v>.><v<^.><<^vv<>><>v><^v>>^^^.v^v>v>^v^>.v<<^>.^v<v>^>vv<#
|
||||
#<<>^^.^>v<vvvv<<^v<v<<<v>.<>>^>^.<<^>^><<>v^.><<<.^^^<<^><<^^>.>vv<v<>>^>^^v<.^>.<v<>^>^<^>^.<>^v.^^^.v><v>^.^v^<<<><<>v.>>>>^<v>..v>^^v<v<^>v<v.>^v>>#
|
||||
#<^.<^^><>^^^<<>>^>.^^^<^<^<^^<^v.^^v>^v<>.^v^^<<..v<^<>>^<..<^.>><v<>^>.^v.>>v^.v..v.<<vv^>^vvv^v<vv<^.^><><><<^v^v.^^<<>^vv>^^>v>^v<<^>^<vvv.><^.^<v>#
|
||||
#<^^v^v>^<^><>v><.><v>^>^<vv<>..v^>^v^>^><>v<^v^<<v<<<<v<v..^^^<><v>v>^vv<^v.<><>vv>>>>v<>^vv<^v<>^^.v>>^^<<.<^<v<>>^>>vv>vv^<v^^>>^<v<.v<v>v<<>.>^>^v>#
|
||||
#<<>>>.<<>^>>v>^<^v>><<^v<><<.^<^<>>><^v>>v>^<^vv.<^^^.vv^<<<>^^>v>^v.>^^v>v.<>vvv><<v>v>^v.<v^<>^>vv<><vv<v^<><vv.>^>.>.v^v.v^vv^<.<>.>vv>^>v<v<v>^<.<#
|
||||
#>^<^<v<^^<^^v><<.<<..>>.>^^v>>v>^^>^^>>>v>v^<v^><>v>><v^<v>^>vvv>><>>vv>.>^.^<>.><v.>^.v<><v<^v><v.v<v<..^>^^<^v^>>.>v.v<><<<v><>^<<^>^>^>^.vv..<>v<^>#
|
||||
#..v<<^v^^>^>^<^<vvv>v<v^^v^.<<vvv.v.v^v>^v^^v>><^><<^v.<vv<><.vv^v<<>^v<<^v^v^^.>^>v<^^v...>>vv.<^v>v^<<^<vv>v^>v<^>v<vv>^<>.>v^^^^.^<>^^.^><.<.>>.><.#
|
||||
#<vv>v^<v^.vv<<.>v<<^v^>>^vv.v>>v>.vv^>>vv.>v>>>^.>>><.^.^<><>^vv<^<>><<vv<<v>^v^>>.<v^<v^<^^^<><>v<>v<....^^><.<^^>v^v>v<v<.><<>>^<>.v.<.vv<.>^.^v^>.>#
|
||||
#<<v<^vv^>v>>^>.>^^^<.>>^<><>>.>^v^<.v^^.^<<^>^.^v^^v<v<><>>.>.<>.^.v>.<v>^><^>v>v<>.^v<><.<<.><<^v<><><^>v^...v<<^^<^>v>^^vv^^vvv>^>v>>.>>v^^.vv>^<v<>#
|
||||
#>v<>^v><>^>>><<^.^v<<v^>v<>>>.^v><^v<<>v<^^.<.><><v>^<><.v<v<<^^^>>><^>^>>.<>vvvv.^^v<<>^<>>><<v^v><v>>>^v.<^>.^>><v><<><vv.v<vv<v^^>v<.<^<^>v^^>v^.><#
|
||||
#><v>vv^<^.<^>v^v^<><><vvv^v>v<>>v^<>^>>>^v^<v>>v<<^.^<v^vvv^^<><vvv.<vv^.>>v^<v.^vv><vv<>v^<^<^^>^^^vv^.<><>><^v.<^<.<>.>^<^<^<>v<^.<v<v<v>^vv><.v<^>>#
|
||||
#>v^.v>^v<>>v^>>>^^^^>.v<<^>^v>.^^>^>v^<^v^^<^^v>v>.v^<v>^v><^^.><^^>>v>v^v<v.<^>><>vv><v^v^><>^vvv>>v>>^v^^<^>>v^<^vv^<^^^^vv<><vv<.v^><v>^^>v^v<><<<<#
|
||||
######################################################################################################################################################.#
|
Loading…
Reference in a new issue