Add 2022 solutions
This commit is contained in:
237
2022/d22.py
Normal file
237
2022/d22.py
Normal file
@@ -0,0 +1,237 @@
|
||||
from lib import *
|
||||
|
||||
EXAMPLE = """ 0..#
|
||||
.#..
|
||||
#...
|
||||
....
|
||||
1..#2...3..#
|
||||
........#...
|
||||
..#....#....
|
||||
..........#.
|
||||
4..#5...
|
||||
.....#..
|
||||
.#......
|
||||
......#.
|
||||
|
||||
10R5L5R10L4R5L5"""
|
||||
|
||||
|
||||
E = (0, 1)
|
||||
S = (1, 0)
|
||||
W = (0, -1)
|
||||
N = (-1, 0)
|
||||
|
||||
DIRS = [
|
||||
E,
|
||||
S,
|
||||
W,
|
||||
N,
|
||||
]
|
||||
|
||||
# XXX: not hands free - i created this manually probably there is some way to
|
||||
# figure it out from the input, but id don't know how right now.
|
||||
trans_example = {
|
||||
(0, N): (1, S),
|
||||
(0, E): (5, W),
|
||||
(0, S): (3, S),
|
||||
(0, W): (2, S),
|
||||
(1, N): (0, S),
|
||||
(1, E): (2, E),
|
||||
(1, S): (4, N),
|
||||
(1, W): (5, N),
|
||||
(2, N): (0, E),
|
||||
(2, E): (3, E),
|
||||
(2, S): (4, E),
|
||||
(2, W): (1, W),
|
||||
(3, N): (0, N),
|
||||
(3, E): (5, S),
|
||||
(3, S): (4, S),
|
||||
(3, W): (2, W),
|
||||
(4, N): (3, N),
|
||||
(4, E): (5, E),
|
||||
(4, S): (1, N),
|
||||
(4, W): (2, N),
|
||||
(5, N): (3, W),
|
||||
(5, E): (0, W),
|
||||
(5, S): (1, E),
|
||||
(5, W): (4, W),
|
||||
}
|
||||
|
||||
trans_input = {
|
||||
(0, N): (5, E),
|
||||
(0, E): (1, E),
|
||||
(0, S): (2, S),
|
||||
(0, W): (3, E),
|
||||
(1, N): (5, N),
|
||||
(1, E): (4, W),
|
||||
(1, S): (2, W),
|
||||
(1, W): (0, W),
|
||||
(2, N): (0, N),
|
||||
(2, E): (1, N),
|
||||
(2, S): (4, S),
|
||||
(2, W): (3, S),
|
||||
(3, N): (2, E),
|
||||
(3, E): (4, E),
|
||||
(3, S): (5, S),
|
||||
(3, W): (0, E),
|
||||
(4, N): (2, N),
|
||||
(4, E): (1, W),
|
||||
(4, S): (5, W),
|
||||
(4, W): (3, W),
|
||||
(5, N): (3, N),
|
||||
(5, E): (4, N),
|
||||
(5, S): (1, S),
|
||||
(5, W): (0, S),
|
||||
}
|
||||
|
||||
def parse_steps(steps):
|
||||
insts = re.compile(r"(\d+)([LR])").findall(steps)
|
||||
lastn = re.compile(r"\d+").findall(steps)[-1]
|
||||
insts.append((lastn, None))
|
||||
return insts
|
||||
|
||||
|
||||
def solve(input: Input):
|
||||
grid, steps = input.text.split("\n\n")
|
||||
insts = parse_steps(steps)
|
||||
|
||||
grid = list(map(list, grid.splitlines()))
|
||||
rows = len(grid)
|
||||
|
||||
startcol = 0
|
||||
while grid[0][startcol] == ' ':
|
||||
startcol += 1
|
||||
pos = (0, startcol)
|
||||
dir = (0, 1)
|
||||
for n, turn in insts:
|
||||
nrow, ncol = pos
|
||||
for _ in range(int(n)):
|
||||
nrow = (nrow + dir[0]) % rows
|
||||
ncol = (ncol + dir[1]) % len(grid[nrow])
|
||||
while grid[nrow][ncol] == ' ':
|
||||
nrow = (nrow + dir[0]) % rows
|
||||
ncol = (ncol + dir[1]) % len(grid[nrow])
|
||||
if grid[nrow][ncol] == '#':
|
||||
break
|
||||
pos = (nrow, ncol)
|
||||
if turn is not None:
|
||||
dir = DIRS[(DIRS.index(dir) + 1 if turn == 'R' else DIRS.index(dir) - 1) % 4]
|
||||
|
||||
return 1000 * (pos[0] + 1) + 4 * (pos[1] + 1) + DIRS.index(dir)
|
||||
|
||||
|
||||
def solve2(input: Input, square_size=4):
|
||||
squares = []
|
||||
grid, steps = input.text.split("\n\n")
|
||||
insts = parse_steps(steps)
|
||||
grid_rows = grid.splitlines()
|
||||
for r in range(0, len(grid_rows), square_size):
|
||||
for c in range(0, len(grid_rows[r]), square_size):
|
||||
square = []
|
||||
for sr in range(r, r + square_size):
|
||||
square.append(grid_rows[sr][c:c+square_size])
|
||||
if square[0][0] != ' ':
|
||||
squares.append(square)
|
||||
|
||||
def flip(n):
|
||||
return square_size - 1 - n
|
||||
|
||||
def teleport(dir, sqi, row, col):
|
||||
if square_size == 4:
|
||||
nsqi, ndir = trans_example[(sqi, dir)]
|
||||
elif square_size == 50:
|
||||
nsqi, ndir = trans_input[(sqi, dir)]
|
||||
else:
|
||||
assert False
|
||||
nrow, ncol = None, None
|
||||
|
||||
if ndir == N:
|
||||
nrow = square_size - 1
|
||||
elif ndir == S:
|
||||
nrow = 0
|
||||
elif ndir == E:
|
||||
ncol = 0
|
||||
elif ndir == W:
|
||||
ncol = square_size - 1
|
||||
|
||||
if dir == N:
|
||||
if ndir == N:
|
||||
ncol = col
|
||||
elif ndir == S:
|
||||
ncol = flip(col)
|
||||
elif ndir == E:
|
||||
nrow = col
|
||||
elif ndir == W:
|
||||
nrow = square_size - 1 - col
|
||||
elif dir == S:
|
||||
if ndir == N:
|
||||
ncol = flip(col)
|
||||
elif ndir == S:
|
||||
ncol = col
|
||||
elif ndir == E:
|
||||
nrow = square_size - 1 - col
|
||||
elif ndir == W:
|
||||
nrow = col
|
||||
elif dir == E:
|
||||
if ndir == N:
|
||||
ncol = row
|
||||
elif ndir == S:
|
||||
ncol = flip(row)
|
||||
elif ndir == E:
|
||||
nrow = row
|
||||
elif ndir == W:
|
||||
nrow = square_size - 1 - row
|
||||
elif dir == W:
|
||||
if ndir == N:
|
||||
ncol = flip(row)
|
||||
elif ndir == S:
|
||||
ncol = row
|
||||
elif ndir == E:
|
||||
nrow = flip(row)
|
||||
elif ndir == W:
|
||||
nrow = row
|
||||
|
||||
assert nrow is not None
|
||||
assert ncol is not None
|
||||
return ndir, nsqi, nrow, ncol
|
||||
|
||||
# for square in squares:
|
||||
# print("\n".join(square), "\n")
|
||||
|
||||
dir, sqi, row, col = E, 0, 0, 0
|
||||
for n, turn in insts:
|
||||
# print(f"{sqi=} {row=} {col=} {dir=}")
|
||||
for _ in range(int(n)):
|
||||
nrow = row + dir[0]
|
||||
ncol = col + dir[1]
|
||||
if nrow < 0 or nrow >= square_size or ncol < 0 or ncol >= square_size:
|
||||
ndir, nsqi, nrow, ncol = teleport(dir, sqi, nrow, ncol)
|
||||
else:
|
||||
ndir, nsqi = dir, sqi
|
||||
if squares[nsqi][nrow][ncol] != '#':
|
||||
dir, sqi, row, col = ndir, nsqi, nrow, ncol
|
||||
if turn is not None:
|
||||
dir = DIRS[(DIRS.index(dir) + 1 if turn == 'R' else DIRS.index(dir) - 1) % 4]
|
||||
print(f"{sqi=} {row=} {col=} {dir=}")
|
||||
|
||||
if square_size == 4:
|
||||
# sqi=2 row=0 col=2 dir=(-1, 0)
|
||||
return 1000 * (4 + 0 + 1) + 4 * (4 + 2 + 1) + DIRS.index((-1, 0))
|
||||
elif square_size == 50:
|
||||
# sqi=1 row=11 col=14 dir=(0, -1)
|
||||
return 1000 * (0 + 11 + 1) + 4 * (100 + 14 + 1) + DIRS.index((0, -1))
|
||||
else:
|
||||
assert False
|
||||
|
||||
def main():
|
||||
DAY_INPUT = "d22.txt"
|
||||
print("Example 1:", solve(Input(EXAMPLE)))
|
||||
print("Solution 1:", solve(Input(DAY_INPUT)))
|
||||
assert solve(Input(DAY_INPUT)) == 149250
|
||||
|
||||
print("Example 2:", solve2(Input(EXAMPLE)))
|
||||
print("Solution 2:", solve2(Input("d22.txt"), 50))
|
||||
return
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user