diff --git a/day22/sol.py b/day22/sol.py index c134d74..725ed74 100644 --- a/day22/sol.py +++ b/day22/sol.py @@ -7,6 +7,10 @@ with open("input") as f: map.append(line.rstrip("\n")) moves = f.readline().strip() +# 0 - E +# 1 - S +# 2 - W +# 3 - N F = { 0: (+1, 0), 1: (0, +1), @@ -17,17 +21,15 @@ F = { #assert len(set(len(l) for l in map)) == 1 class Map: - def __init__(self, map): + def __init__(self, map, region_size=50): 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.col = self.starts[0] + self.col = 0 self.face = 0 + self.region_size = region_size + + while self.map[self.row][self.col] == ' ': + self.col += 1 # 9' # 1 2 @@ -56,90 +58,91 @@ class Map: if (r,f) != orig: print("!!", s) 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): - # 0 - E - # 1 - S - # 2 - W - # 3 - N + R = self.region_size dx, dy = F[face] - r = self.region(x,y) - if 0 <= (x%50 + dx) < 50 and 0 <= (y%50 + dy) < 50: + if 0 <= (x%R + dx) < R and 0 <= (y%R + dy) < R: x, y = x+dx, y+dy else: + r = self.region(x,y) + u = (x+dx) % R + v = (y+dy) % R + new_r, rotate = self.region_map[r][face] - x = (x+dx) % 50 - y = (y+dy) % 50 if rotate == 0: pass elif rotate == -1: - x, y = y, 50-x-1 + u, v = v, R-u-1 elif rotate == 1: - x, y = 50-y-1, x + u, v = R-v-1, u elif rotate == 2: - x, y = 50-x-1, 50-y-1 - x, y = self.in_region(x, y, new_r) + u, v = R-u-1, R-v-1 + x, y = self.to_abs(u, v, new_r) face = (face + rotate) % 4 c = self.map[y][x] assert c != ' ' return x, y, face, c - @staticmethod - def in_region(x, y, r): - """returns the absolute coords if the local (x,y) in region r""" - x %= 50 - y %= 50 + def to_abs(self, u, v, r): + """returns the absolute coords of the local point (u,v) in region r""" + R = self.region_size + u %= R + v %= R rx = r % 3 ry = r // 3 - return (rx*50 + x), (ry*50 + y) + return (rx*R + u), (ry*R + v) - @staticmethod - def region(x, y): - return y//50 * 3 + x//50 - - 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 region(self, x, y): + R = self.region_size + return y//R * 3 + x//R def turnLeft(self): self.face = (self.face - 1) % 4 def turnRight(self): 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: - x,y,f,c = self.nextTile(self.col, self.row, self.face) - if c == '#': + x,y,face,c = self.nextTile(x, y, face) + if c == '#' and noclip: break - pass#break + n -= 1 self.row = y self.col = x - self.face = f - #self.map[y][x] = '>v<^'[self.face] - n -= 1 - print(self.row+1, self.col+1) + self.face = face + #print(self.pos()) def pos(self): return self.row+1, self.col+1 @@ -148,15 +151,11 @@ class Map: r, c = self.pos() return r*1000 + c*4 + self.face -print(moves) +#print(moves) m = Map(map) +#m.set_simple_region_map() -for _ in range(4): - #m.walk(50) - print("---") - -#blah i = 0 while i < len(moves): if moves[i].isdigit():