diff --git a/day22/sol.py b/day22/sol.py index e1b39a5..c134d74 100644 --- a/day22/sol.py +++ b/day22/sol.py @@ -16,7 +16,6 @@ F = { #assert len(set(len(l) for l in map)) == 1 - class Map: def __init__(self, map): self.map = map @@ -30,14 +29,79 @@ class Map: self.col = self.starts[0] self.face = 0 - def nextTile(self): - x,y = self.col, self.row - f = self.face + # 9' + # 1 2 + # \ 4 \ + # 6 7 + # 9 \ + self.region_map = { + # R D L U + 1: [(2,0), (4, 0), (6,2), (9, 1)], + 4: [(2,-1), (7,0), (6,-1), (1, 0)], + 7: [(2,2), (9,+1), (6,0), (4,0)], + 6: [(7,0), (9,0), (1,2), (4,+1)], + 9: [(7,-1), (2,0), (1,-1), (6,0)], + 2: [(7,2), (4,+1), (1, 0), (9,0)], + } + + ok = True + for f in range(4): + for r in self.region_map: + orig = (r,f) + s = repr(orig) + for _ in range(4): + r, h = self.region_map[r][f] + f = (f+h)%4 + s += "-> {} {}".format(r, f) + if (r,f) != orig: + print("!!", s) + ok = False + assert ok, "region topography failure" + + def nextTile(self, x, y, face): # 0 - E # 1 - S # 2 - W # 3 - N - dx, dy = F[self.face] + dx, dy = F[face] + r = self.region(x,y) + if 0 <= (x%50 + dx) < 50 and 0 <= (y%50 + dy) < 50: + x, y = x+dx, y+dy + else: + 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 + elif rotate == 1: + x, y = 50-y-1, x + elif rotate == 2: + x, y = 50-x-1, 50-y-1 + x, y = self.in_region(x, y, 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 + rx = r % 3 + ry = r // 3 + return (rx*50 + x), (ry*50 + y) + + @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 @@ -66,26 +130,33 @@ class Map: self.face = (self.face + 1) % 4 def walk(self, n): while n > 0: - x,y,c = self.nextTile() + x,y,f,c = self.nextTile(self.col, self.row, self.face) if c == '#': break + pass#break self.row = y self.col = x + self.face = f #self.map[y][x] = '>v<^'[self.face] n -= 1 - print(self.row, self.col) + print(self.row+1, self.col+1) def pos(self): return self.row+1, self.col+1 def score(self): r, c = self.pos() - return r*1000 + c *4 + self.face + return r*1000 + c*4 + self.face print(moves) m = Map(map) +for _ in range(4): + #m.walk(50) + print("---") + +#blah i = 0 while i < len(moves): if moves[i].isdigit():