Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3732e70ef7 | ||
|
b0cc6b4a46 | ||
|
8c24b9f9e2 | ||
|
dca6f6a08f | ||
|
8d7a20f575 | ||
|
3934dfd152 | ||
|
b656e8929e | ||
|
c9c69f479b | ||
|
72ebcfff1f | ||
|
dd72bb3238 | ||
|
c1dd74c57d |
@@ -178,7 +178,7 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
|
|||||||
|
|
||||||
answer_1 = sum(
|
answer_1 = sum(
|
||||||
(i_blueprint + 1) * run(blueprint, 24)
|
(i_blueprint + 1) * run(blueprint, 24)
|
||||||
for i_blueprint, blueprint in enumerate(tqdm(blueprints))
|
for i_blueprint, blueprint in enumerate(blueprints)
|
||||||
)
|
)
|
||||||
print(f"answer 1 is {answer_1}")
|
print(f"answer 1 is {answer_1}")
|
||||||
|
|
||||||
|
@@ -1,26 +1,18 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class Number:
|
class Number:
|
||||||
index: int
|
current: int
|
||||||
value: int
|
value: int
|
||||||
|
|
||||||
def __init__(self, index: int, value: int):
|
def __init__(self, value: int):
|
||||||
self.index = index
|
self.current = 0
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if isinstance(other, Number):
|
|
||||||
return self.index == other.index
|
|
||||||
elif isinstance(other, int):
|
|
||||||
return self.value == other
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
return hash(self.index)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.value)
|
return str(self.value)
|
||||||
|
|
||||||
@@ -32,36 +24,51 @@ def decrypt(numbers: list[Number], key: int, rounds: int) -> int:
|
|||||||
|
|
||||||
numbers = numbers.copy()
|
numbers = numbers.copy()
|
||||||
original = numbers.copy()
|
original = numbers.copy()
|
||||||
numbers2index = {number: number.index for number in numbers}
|
|
||||||
|
|
||||||
def swap(lhs: Number, rhs: Number):
|
for index, number in enumerate(numbers):
|
||||||
i1, i2 = numbers2index[lhs], numbers2index[rhs]
|
number.current = index
|
||||||
numbers[i1], numbers[i2] = numbers[i2], numbers[i1]
|
|
||||||
numbers2index[lhs], numbers2index[rhs] = i2, i1
|
|
||||||
|
|
||||||
def move(index: int, value: int):
|
|
||||||
assert value >= 0
|
|
||||||
while value > 0:
|
|
||||||
if index == len(numbers) - 1:
|
|
||||||
swap(numbers[0], numbers[-1])
|
|
||||||
index, value = 0, value - 1
|
|
||||||
else:
|
|
||||||
swap(numbers[index + 1], numbers[index])
|
|
||||||
index, value = index + 1, value - 1
|
|
||||||
|
|
||||||
for _ in range(rounds):
|
for _ in range(rounds):
|
||||||
for number in original:
|
for number in original:
|
||||||
index = numbers2index[number]
|
index = number.current
|
||||||
move(index, (number.value * key) % (len(numbers) - 1))
|
offset = (number.value * key) % (len(numbers) - 1)
|
||||||
|
target = index + offset
|
||||||
|
|
||||||
index_of_0 = numbers.index(0)
|
# need to wrap
|
||||||
|
if target >= len(numbers):
|
||||||
|
target = offset - (len(numbers) - index) + 1
|
||||||
|
|
||||||
|
for number_2 in numbers[target:index]:
|
||||||
|
number_2.current += 1
|
||||||
|
|
||||||
|
numbers = (
|
||||||
|
numbers[:target]
|
||||||
|
+ [number]
|
||||||
|
+ numbers[target:index]
|
||||||
|
+ numbers[index + 1 :]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for number_2 in numbers[index : target + 1]:
|
||||||
|
number_2.current -= 1
|
||||||
|
|
||||||
|
numbers = (
|
||||||
|
numbers[:index]
|
||||||
|
+ numbers[index + 1 : target + 1]
|
||||||
|
+ [number]
|
||||||
|
+ numbers[target + 1 :]
|
||||||
|
)
|
||||||
|
number.current = target
|
||||||
|
|
||||||
|
index_of_0 = next(
|
||||||
|
filter(lambda index: numbers[index].value == 0, range(len(numbers)))
|
||||||
|
)
|
||||||
return sum(
|
return sum(
|
||||||
numbers[(index_of_0 + offset) % len(numbers)].value * key
|
numbers[(index_of_0 + offset) % len(numbers)].value * key
|
||||||
for offset in (1000, 2000, 3000)
|
for offset in (1000, 2000, 3000)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
numbers = [Number(i, int(x)) for i, x in enumerate(sys.stdin.readlines())]
|
numbers = [Number(int(x)) for i, x in enumerate(sys.stdin.readlines())]
|
||||||
|
|
||||||
answer_1 = decrypt(numbers, 1, 1)
|
answer_1 = decrypt(numbers, 1, 1)
|
||||||
print(f"answer 1 is {answer_1}")
|
print(f"answer 1 is {answer_1}")
|
||||||
|
109
2022/day21.py
Normal file
109
2022/day21.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import operator
|
||||||
|
import sys
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
|
||||||
|
def compute(monkeys: dict[str, int | tuple[str, str, str]], monkey: str) -> int:
|
||||||
|
value = monkeys[monkey]
|
||||||
|
if isinstance(value, int):
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
op: dict[str, Callable[[int, int], int]] = {
|
||||||
|
"+": operator.add,
|
||||||
|
"-": operator.sub,
|
||||||
|
"*": operator.mul,
|
||||||
|
"/": operator.floordiv,
|
||||||
|
}
|
||||||
|
value = op[value[1]](compute(monkeys, value[0]), compute(monkeys, value[2]))
|
||||||
|
monkeys[monkey] = value
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def invert(
|
||||||
|
monkeys: dict[str, int | tuple[str, str, str]], monkey: str, target: int
|
||||||
|
) -> dict[str, int | tuple[str, str, str]]:
|
||||||
|
"""
|
||||||
|
Revert the given mapping from monkey name to value or operation such that
|
||||||
|
the value from 'monkey' is computable by inverting operation until the root is
|
||||||
|
found.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
monkeys: Dictionary of monkeys, that will be updated and returned.
|
||||||
|
monkey: Name of the monkey to start from.
|
||||||
|
target: Target value to set for the monkey that depends on root.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The given dictionary of monkeys.
|
||||||
|
"""
|
||||||
|
|
||||||
|
monkeys = monkeys.copy()
|
||||||
|
|
||||||
|
depends: dict[str, str] = {}
|
||||||
|
for m, v in monkeys.items():
|
||||||
|
if isinstance(v, int):
|
||||||
|
continue
|
||||||
|
|
||||||
|
op1, _, op2 = v
|
||||||
|
|
||||||
|
assert op1 not in depends
|
||||||
|
assert op2 not in depends
|
||||||
|
depends[op1] = m
|
||||||
|
depends[op2] = m
|
||||||
|
|
||||||
|
invert_op = {"+": "-", "-": "+", "*": "/", "/": "*"}
|
||||||
|
|
||||||
|
current = monkey
|
||||||
|
while True:
|
||||||
|
dep = depends[current]
|
||||||
|
|
||||||
|
if dep == "root":
|
||||||
|
monkeys[current] = target
|
||||||
|
break
|
||||||
|
|
||||||
|
val = monkeys[dep]
|
||||||
|
assert not isinstance(val, int)
|
||||||
|
|
||||||
|
op1, ope, op2 = val
|
||||||
|
|
||||||
|
if op1 == current:
|
||||||
|
monkeys[current] = (dep, invert_op[ope], op2)
|
||||||
|
elif ope in ("+", "*"):
|
||||||
|
monkeys[current] = (dep, invert_op[ope], op1)
|
||||||
|
else:
|
||||||
|
monkeys[current] = (op1, ope, dep)
|
||||||
|
|
||||||
|
current = dep
|
||||||
|
|
||||||
|
return monkeys
|
||||||
|
|
||||||
|
|
||||||
|
lines = sys.stdin.read().splitlines()
|
||||||
|
|
||||||
|
monkeys: dict[str, int | tuple[str, str, str]] = {}
|
||||||
|
|
||||||
|
op_monkeys: set[str] = set()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
parts = line.split(":")
|
||||||
|
name = parts[0].strip()
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = int(parts[1].strip())
|
||||||
|
monkeys[name] = value
|
||||||
|
except ValueError:
|
||||||
|
op1, ope, op2 = parts[1].strip().split()
|
||||||
|
monkeys[name] = (op1, ope, op2)
|
||||||
|
|
||||||
|
op_monkeys.add(name)
|
||||||
|
|
||||||
|
|
||||||
|
answer_1 = compute(monkeys.copy(), "root")
|
||||||
|
print(f"answer 1 is {answer_1}")
|
||||||
|
|
||||||
|
# assume the second operand of 'root' can be computed, and the first one depends on
|
||||||
|
# humn, which is the case is my input and the test input
|
||||||
|
p1, _, p2 = monkeys["root"] # type: ignore
|
||||||
|
answer_2 = compute(invert(monkeys, "humn", compute(monkeys.copy(), p2)), "humn")
|
||||||
|
print(f"answer 2 is {answer_2}")
|
225
2022/day22.py
Normal file
225
2022/day22.py
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
VOID, EMPTY, WALL = 0, 1, 2
|
||||||
|
TILE_FROM_CHAR = {" ": VOID, ".": EMPTY, "#": WALL}
|
||||||
|
|
||||||
|
SCORES = {"E": 0, "S": 1, "W": 2, "N": 3}
|
||||||
|
|
||||||
|
|
||||||
|
board_map_s, direction_s = sys.stdin.read().split("\n\n")
|
||||||
|
|
||||||
|
# board
|
||||||
|
board_lines = board_map_s.splitlines()
|
||||||
|
max_line = max(len(line) for line in board_lines)
|
||||||
|
board = np.array(
|
||||||
|
[
|
||||||
|
[TILE_FROM_CHAR[c] for c in row] + [VOID] * (max_line - len(row))
|
||||||
|
for row in board_map_s.splitlines()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
directions = [
|
||||||
|
int(p1) if p2 else p1 for p1, p2 in re.findall(R"(([0-9])+|L|R)", direction_s)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# find on each row and column the first and last non-void
|
||||||
|
row_first_non_void = np.argmax(board != VOID, axis=1)
|
||||||
|
row_last_non_void = board.shape[1] - np.argmax(board[:, ::-1] != VOID, axis=1) - 1
|
||||||
|
col_first_non_void = np.argmax(board != VOID, axis=0)
|
||||||
|
col_last_non_void = board.shape[0] - np.argmax(board[::-1, :] != VOID, axis=0) - 1
|
||||||
|
|
||||||
|
|
||||||
|
faces = np.zeros_like(board)
|
||||||
|
size = np.gcd(board.shape[0], board.shape[1])
|
||||||
|
for row in range(0, board.shape[0], size):
|
||||||
|
for col in range(row_first_non_void[row], row_last_non_void[row], size):
|
||||||
|
faces[row : row + size, col : col + size] = faces.max() + 1
|
||||||
|
|
||||||
|
SIZE = np.gcd(*board.shape)
|
||||||
|
|
||||||
|
# TODO: deduce this from the actual cube...
|
||||||
|
faces_wrap: dict[int, dict[str, Callable[[int, int], tuple[int, int, str]]]]
|
||||||
|
if board.shape == (12, 16): # example
|
||||||
|
faces_wrap = {
|
||||||
|
1: {
|
||||||
|
"W": lambda y, x: (4, 4 + y, "S"), # 3N
|
||||||
|
"N": lambda y, x: (4, 11 - x, "S"), # 2N
|
||||||
|
"E": lambda y, x: (11 - y, 15, "W"), # 6E
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
"W": lambda y, x: (11, 19 - y, "N"), # 6S
|
||||||
|
"N": lambda y, x: (0, 11 - y, "S"), # 1N
|
||||||
|
"S": lambda y, x: (11, 11 - x, "N"), # 5S
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
"N": lambda y, x: (x - 4, 8, "E"), # 1W
|
||||||
|
"S": lambda y, x: (15 - x, 8, "E"), # 5W
|
||||||
|
},
|
||||||
|
4: {"E": lambda y, x: (8, 19 - y, "S")}, # 6N
|
||||||
|
5: {
|
||||||
|
"W": lambda y, x: (7, 15 - y, "N"), # 3S
|
||||||
|
"S": lambda y, x: (7, 11 - x, "N"), # 2S
|
||||||
|
},
|
||||||
|
6: {
|
||||||
|
"N": lambda y, x: (19 - x, 11, "W"), # 4E
|
||||||
|
"E": lambda y, x: (11 - y, 11, "W"), # 1E
|
||||||
|
"S": lambda y, x: (19 - x, 0, "E"), # 2W
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
else:
|
||||||
|
faces_wrap = {
|
||||||
|
1: {
|
||||||
|
"W": lambda y, x: (3 * SIZE - y - 1, 0, "E"), # 4W
|
||||||
|
"N": lambda y, x: (2 * SIZE + x, 0, "E"), # 6W
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
"N": lambda y, x: (4 * SIZE - 1, x - 2 * SIZE, "N"), # 6S
|
||||||
|
"E": lambda y, x: (3 * SIZE - y - 1, 2 * SIZE - 1, "W"), # 5E
|
||||||
|
"S": lambda y, x: (x - SIZE, 2 * SIZE - 1, "W"), # 3E
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
"W": lambda y, x: (2 * SIZE, y - SIZE, "S"), # 4N
|
||||||
|
"E": lambda y, x: (SIZE - 1, SIZE + y, "N"), # 2S
|
||||||
|
},
|
||||||
|
4: {
|
||||||
|
"W": lambda y, x: (3 * SIZE - y - 1, SIZE, "E"), # 1W
|
||||||
|
"N": lambda y, x: (SIZE + x, SIZE, "E"), # 3W
|
||||||
|
},
|
||||||
|
5: {
|
||||||
|
"E": lambda y, x: (3 * SIZE - y - 1, 3 * SIZE - 1, "W"), # 2E
|
||||||
|
"S": lambda y, x: (2 * SIZE + x, SIZE - 1, "W"), # 6E
|
||||||
|
},
|
||||||
|
6: {
|
||||||
|
"W": lambda y, x: (0, y - 2 * SIZE, "S"), # 1N
|
||||||
|
"E": lambda y, x: (3 * SIZE - 1, y - 2 * SIZE, "N"), # 5S
|
||||||
|
"S": lambda y, x: (0, x + 2 * SIZE, "S"), # 2N
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def wrap_part_1(y0: int, x0: int, r0: str) -> tuple[int, int, str]:
|
||||||
|
if r0 == "E":
|
||||||
|
return y0, row_first_non_void[y0], r0
|
||||||
|
elif r0 == "S":
|
||||||
|
return col_first_non_void[x0], x0, r0
|
||||||
|
elif r0 == "W":
|
||||||
|
return y0, row_last_non_void[y0], r0
|
||||||
|
elif r0 == "N":
|
||||||
|
return col_last_non_void[x0], x0, r0
|
||||||
|
|
||||||
|
assert False
|
||||||
|
|
||||||
|
|
||||||
|
def wrap_part_2(y0: int, x0: int, r0: str) -> tuple[int, int, str]:
|
||||||
|
cube = faces[y0, x0]
|
||||||
|
assert r0 in faces_wrap[cube]
|
||||||
|
return faces_wrap[cube][r0](y0, x0)
|
||||||
|
|
||||||
|
|
||||||
|
def run(wrap: Callable[[int, int, str], tuple[int, int, str]]) -> tuple[int, int, str]:
|
||||||
|
|
||||||
|
y0 = 0
|
||||||
|
x0 = np.where(board[0] == EMPTY)[0][0]
|
||||||
|
r0 = "E"
|
||||||
|
|
||||||
|
for direction in directions:
|
||||||
|
if isinstance(direction, int):
|
||||||
|
while direction > 0:
|
||||||
|
if r0 == "E":
|
||||||
|
xi = np.where(board[y0, x0 + 1 : x0 + direction + 1] == WALL)[0]
|
||||||
|
if len(xi):
|
||||||
|
x0 = x0 + xi[0]
|
||||||
|
direction = 0
|
||||||
|
elif (
|
||||||
|
x0 + direction < board.shape[1]
|
||||||
|
and board[y0, x0 + direction] == EMPTY
|
||||||
|
):
|
||||||
|
x0 = x0 + direction
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
|
||||||
|
if board[y0_t, x0_t] == WALL:
|
||||||
|
x0 = row_last_non_void[y0]
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
direction = direction - (row_last_non_void[y0] - x0) - 1
|
||||||
|
y0, x0, r0 = y0_t, x0_t, r0_t
|
||||||
|
elif r0 == "S":
|
||||||
|
yi = np.where(board[y0 + 1 : y0 + direction + 1, x0] == WALL)[0]
|
||||||
|
if len(yi):
|
||||||
|
y0 = y0 + yi[0]
|
||||||
|
direction = 0
|
||||||
|
elif (
|
||||||
|
y0 + direction < board.shape[0]
|
||||||
|
and board[y0 + direction, x0] == EMPTY
|
||||||
|
):
|
||||||
|
y0 = y0 + direction
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
|
||||||
|
if board[y0_t, x0_t] == WALL:
|
||||||
|
y0 = col_last_non_void[x0]
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
direction = direction - (col_last_non_void[x0] - y0) - 1
|
||||||
|
y0, x0, r0 = y0_t, x0_t, r0_t
|
||||||
|
elif r0 == "W":
|
||||||
|
left = max(x0 - direction - 1, 0)
|
||||||
|
xi = np.where(board[y0, left:x0] == WALL)[0]
|
||||||
|
if len(xi):
|
||||||
|
x0 = left + xi[-1] + 1
|
||||||
|
direction = 0
|
||||||
|
elif x0 - direction >= 0 and board[y0, x0 - direction] == EMPTY:
|
||||||
|
x0 = x0 - direction
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
|
||||||
|
if board[y0_t, x0_t] == WALL:
|
||||||
|
x0 = row_first_non_void[y0]
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
direction = direction - (x0 - row_first_non_void[y0]) - 1
|
||||||
|
y0, x0, r0 = y0_t, x0_t, r0_t
|
||||||
|
elif r0 == "N":
|
||||||
|
top = max(y0 - direction - 1, 0)
|
||||||
|
yi = np.where(board[top:y0, x0] == WALL)[0]
|
||||||
|
if len(yi):
|
||||||
|
y0 = top + yi[-1] + 1
|
||||||
|
direction = 0
|
||||||
|
elif y0 - direction >= 0 and board[y0 - direction, x0] == EMPTY:
|
||||||
|
y0 = y0 - direction
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
|
||||||
|
if board[y0_t, x0_t] == WALL:
|
||||||
|
y0 = col_first_non_void[x0]
|
||||||
|
direction = 0
|
||||||
|
else:
|
||||||
|
direction = direction - (y0 - col_first_non_void[x0]) - 1
|
||||||
|
y0, x0, r0 = y0_t, x0_t, r0_t
|
||||||
|
else:
|
||||||
|
r0 = {
|
||||||
|
"E": {"L": "N", "R": "S"},
|
||||||
|
"N": {"L": "W", "R": "E"},
|
||||||
|
"W": {"L": "S", "R": "N"},
|
||||||
|
"S": {"L": "E", "R": "W"},
|
||||||
|
}[r0][direction]
|
||||||
|
|
||||||
|
return y0, x0, r0
|
||||||
|
|
||||||
|
|
||||||
|
y1, x1, r1 = run(wrap_part_1)
|
||||||
|
answer_1 = 1000 * (1 + y1) + 4 * (1 + x1) + SCORES[r1]
|
||||||
|
print(f"answer 1 is {answer_1}")
|
||||||
|
|
||||||
|
y2, x2, r2 = run(wrap_part_2)
|
||||||
|
answer_2 = 1000 * (1 + y2) + 4 * (1 + x2) + SCORES[r2]
|
||||||
|
print(f"answer 2 is {answer_2}")
|
3
2022/day23.py
Normal file
3
2022/day23.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
3
2022/day24.py
Normal file
3
2022/day24.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
3
2022/day25.py
Normal file
3
2022/day25.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
|||||||
|
root: pppw + sjmn
|
||||||
|
dbpl: 5
|
||||||
|
cczh: sllz + lgvd
|
||||||
|
zczc: 2
|
||||||
|
ptdq: humn - dvpt
|
||||||
|
dvpt: 3
|
||||||
|
lfqf: 4
|
||||||
|
humn: 5
|
||||||
|
ljgn: 2
|
||||||
|
sjmn: drzm * dbpl
|
||||||
|
sllz: 4
|
||||||
|
pppw: cczh / lfqf
|
||||||
|
lgvd: ljgn * ptdq
|
||||||
|
drzm: hmdt - zczc
|
||||||
|
hmdt: 32
|
||||||
|
@@ -0,0 +1,14 @@
|
|||||||
|
...#
|
||||||
|
.#..
|
||||||
|
#...
|
||||||
|
....
|
||||||
|
...#.......#
|
||||||
|
........#...
|
||||||
|
..#....#....
|
||||||
|
..........#.
|
||||||
|
...#....
|
||||||
|
.....#..
|
||||||
|
.#......
|
||||||
|
......#.
|
||||||
|
|
||||||
|
10R5L5R10L4R5L5
|
||||||
|
Reference in New Issue
Block a user