parent
77f02a8217
commit
a299c90401
137
day22/sol.py
137
day22/sol.py
|
@ -7,6 +7,10 @@ with open("input") as f:
|
||||||
map.append(line.rstrip("\n"))
|
map.append(line.rstrip("\n"))
|
||||||
moves = f.readline().strip()
|
moves = f.readline().strip()
|
||||||
|
|
||||||
|
# 0 - E
|
||||||
|
# 1 - S
|
||||||
|
# 2 - W
|
||||||
|
# 3 - N
|
||||||
F = {
|
F = {
|
||||||
0: (+1, 0),
|
0: (+1, 0),
|
||||||
1: (0, +1),
|
1: (0, +1),
|
||||||
|
@ -17,17 +21,15 @@ F = {
|
||||||
#assert len(set(len(l) for l in map)) == 1
|
#assert len(set(len(l) for l in map)) == 1
|
||||||
|
|
||||||
class Map:
|
class Map:
|
||||||
def __init__(self, map):
|
def __init__(self, map, region_size=50):
|
||||||
self.map = map
|
self.map = map
|
||||||
self.starts = {}
|
|
||||||
for row in range(len(self.map)):
|
|
||||||
i = 0
|
|
||||||
while self.map[row][i] == ' ':
|
|
||||||
i += 1
|
|
||||||
self.starts[row] = i
|
|
||||||
self.row = 0
|
self.row = 0
|
||||||
self.col = self.starts[0]
|
self.col = 0
|
||||||
self.face = 0
|
self.face = 0
|
||||||
|
self.region_size = region_size
|
||||||
|
|
||||||
|
while self.map[self.row][self.col] == ' ':
|
||||||
|
self.col += 1
|
||||||
|
|
||||||
# 9'
|
# 9'
|
||||||
# 1 2
|
# 1 2
|
||||||
|
@ -56,90 +58,91 @@ class Map:
|
||||||
if (r,f) != orig:
|
if (r,f) != orig:
|
||||||
print("!!", s)
|
print("!!", s)
|
||||||
ok = False
|
ok = False
|
||||||
assert ok, "region topography failure"
|
assert ok, "topology failure"
|
||||||
|
|
||||||
|
def set_simple_region_map(self):
|
||||||
|
R = self.region_size
|
||||||
|
def exists(x,y):
|
||||||
|
return 0 <= y < len(self.map) and 0 <= x < len(self.map[y]) and self.map[y][x] != ' '
|
||||||
|
for y in range(0,len(self.map), R):
|
||||||
|
for x in range(0, len(self.map[y]), R):
|
||||||
|
if exists(x,y):
|
||||||
|
warps = []
|
||||||
|
for f in range(4):
|
||||||
|
dx, dy = F[f]
|
||||||
|
dx, dy = dx*R, dy*R
|
||||||
|
x1, y1 = x+dx, y+dy
|
||||||
|
if exists(x1, y1):
|
||||||
|
dest = self.region(x1,y1)
|
||||||
|
else:
|
||||||
|
if dy:
|
||||||
|
y1 %= len(self.map)
|
||||||
|
while not exists(x1, y1):
|
||||||
|
y1 = (y1+dy)%len(self.map)
|
||||||
|
if dx:
|
||||||
|
x1 %= len(self.map[y1])
|
||||||
|
while not exists(x1, y1):
|
||||||
|
x1 = (x1+dx)%len(self.map[y1])
|
||||||
|
dest = self.region(x1, y1)
|
||||||
|
warps.append((dest, 0))
|
||||||
|
r = self.region(x,y)
|
||||||
|
self.region_map[r] = warps
|
||||||
|
print(self.region_map)
|
||||||
|
|
||||||
def nextTile(self, x, y, face):
|
def nextTile(self, x, y, face):
|
||||||
# 0 - E
|
R = self.region_size
|
||||||
# 1 - S
|
|
||||||
# 2 - W
|
|
||||||
# 3 - N
|
|
||||||
dx, dy = F[face]
|
dx, dy = F[face]
|
||||||
r = self.region(x,y)
|
if 0 <= (x%R + dx) < R and 0 <= (y%R + dy) < R:
|
||||||
if 0 <= (x%50 + dx) < 50 and 0 <= (y%50 + dy) < 50:
|
|
||||||
x, y = x+dx, y+dy
|
x, y = x+dx, y+dy
|
||||||
else:
|
else:
|
||||||
|
r = self.region(x,y)
|
||||||
|
u = (x+dx) % R
|
||||||
|
v = (y+dy) % R
|
||||||
|
|
||||||
new_r, rotate = self.region_map[r][face]
|
new_r, rotate = self.region_map[r][face]
|
||||||
x = (x+dx) % 50
|
|
||||||
y = (y+dy) % 50
|
|
||||||
|
|
||||||
if rotate == 0:
|
if rotate == 0:
|
||||||
pass
|
pass
|
||||||
elif rotate == -1:
|
elif rotate == -1:
|
||||||
x, y = y, 50-x-1
|
u, v = v, R-u-1
|
||||||
elif rotate == 1:
|
elif rotate == 1:
|
||||||
x, y = 50-y-1, x
|
u, v = R-v-1, u
|
||||||
elif rotate == 2:
|
elif rotate == 2:
|
||||||
x, y = 50-x-1, 50-y-1
|
u, v = R-u-1, R-v-1
|
||||||
x, y = self.in_region(x, y, new_r)
|
x, y = self.to_abs(u, v, new_r)
|
||||||
face = (face + rotate) % 4
|
face = (face + rotate) % 4
|
||||||
c = self.map[y][x]
|
c = self.map[y][x]
|
||||||
assert c != ' '
|
assert c != ' '
|
||||||
return x, y, face, c
|
return x, y, face, c
|
||||||
|
|
||||||
@staticmethod
|
def to_abs(self, u, v, r):
|
||||||
def in_region(x, y, r):
|
"""returns the absolute coords of the local point (u,v) in region r"""
|
||||||
"""returns the absolute coords if the local (x,y) in region r"""
|
R = self.region_size
|
||||||
x %= 50
|
u %= R
|
||||||
y %= 50
|
v %= R
|
||||||
rx = r % 3
|
rx = r % 3
|
||||||
ry = r // 3
|
ry = r // 3
|
||||||
return (rx*50 + x), (ry*50 + y)
|
return (rx*R + u), (ry*R + v)
|
||||||
|
|
||||||
@staticmethod
|
def region(self, x, y):
|
||||||
def region(x, y):
|
R = self.region_size
|
||||||
return y//50 * 3 + x//50
|
return y//R * 3 + x//R
|
||||||
|
|
||||||
def warp(x,y,face):
|
|
||||||
r = self.region(x,y)
|
|
||||||
s = 0
|
|
||||||
|
|
||||||
if dx:
|
|
||||||
x += dx
|
|
||||||
if x < self.starts[y]:
|
|
||||||
x = len(self.map[y])-1
|
|
||||||
elif x >= len(self.map[y]):
|
|
||||||
x = self.starts[y]
|
|
||||||
|
|
||||||
if dy:
|
|
||||||
for _ in range(999):
|
|
||||||
y += dy
|
|
||||||
if y < 0:
|
|
||||||
y = len(self.map)-1
|
|
||||||
elif y >= len(self.map):
|
|
||||||
y = 0
|
|
||||||
if x > len(self.map[y]) or self.map[y][x] == ' ':
|
|
||||||
continue
|
|
||||||
break
|
|
||||||
|
|
||||||
assert self.map[y][x] != ' '
|
|
||||||
return x, y, self.map[y][x]
|
|
||||||
|
|
||||||
def turnLeft(self):
|
def turnLeft(self):
|
||||||
self.face = (self.face - 1) % 4
|
self.face = (self.face - 1) % 4
|
||||||
def turnRight(self):
|
def turnRight(self):
|
||||||
self.face = (self.face + 1) % 4
|
self.face = (self.face + 1) % 4
|
||||||
def walk(self, n):
|
def walk(self, n, noclip=True):
|
||||||
|
x, y, face = self.col, self.row, self.face
|
||||||
while n > 0:
|
while n > 0:
|
||||||
x,y,f,c = self.nextTile(self.col, self.row, self.face)
|
x,y,face,c = self.nextTile(x, y, face)
|
||||||
if c == '#':
|
if c == '#' and noclip:
|
||||||
break
|
break
|
||||||
pass#break
|
n -= 1
|
||||||
self.row = y
|
self.row = y
|
||||||
self.col = x
|
self.col = x
|
||||||
self.face = f
|
self.face = face
|
||||||
#self.map[y][x] = '>v<^'[self.face]
|
#print(self.pos())
|
||||||
n -= 1
|
|
||||||
print(self.row+1, self.col+1)
|
|
||||||
|
|
||||||
def pos(self):
|
def pos(self):
|
||||||
return self.row+1, self.col+1
|
return self.row+1, self.col+1
|
||||||
|
@ -148,15 +151,11 @@ class Map:
|
||||||
r, c = self.pos()
|
r, c = self.pos()
|
||||||
return r*1000 + c*4 + self.face
|
return r*1000 + c*4 + self.face
|
||||||
|
|
||||||
print(moves)
|
#print(moves)
|
||||||
|
|
||||||
m = Map(map)
|
m = Map(map)
|
||||||
|
#m.set_simple_region_map()
|
||||||
|
|
||||||
for _ in range(4):
|
|
||||||
#m.walk(50)
|
|
||||||
print("---")
|
|
||||||
|
|
||||||
#blah
|
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(moves):
|
while i < len(moves):
|
||||||
if moves[i].isdigit():
|
if moves[i].isdigit():
|
||||||
|
|
Loading…
Reference in New Issue