# Copyright (C) 2008 Nikhil Marathe # This file is in the public domain # Attribution would be good though. import sys from operator import add DEBUG = len(sys.argv) > 2 def debug(msg): if DEBUG: print msg # CORE CONSTANTS N, S, W, E = 1, 2, 4, 8 LEFT = {N:W, W:S, S:E, E:N} RIGHT = {N:E, E:S, S:W, W:N} OPP = {N:S, S:N, W:E, E:W} DELTAS = {N:(0, -1), S:(0, 1), W:(-1, 0), E:(1, 0)} # this is cool if you ever go to multi dimensions def coords(base_coords, dir): return tuple(map(add, base_coords, DELTAS[dir])) class Cell: def __init__(self): self.dirs = 0 def add_dir(self, dir): self.dirs |= dir def code(self): return "%x"%self.dirs def __str__(self): return "DIR:%s"%self.code() class Maze: def __init__(self): self.grid = {} self.start = None self.current = None self.facing = S # since start always on north side def cell(self, coord): if coord not in self.grid: return None return self.grid[coord] def set_cell(self, coord, c): self.grid[coord] = c def walk(self, str, start_coord): str = str[1:-1] self.current = start_coord for char in str: if char == 'W': self.cell(self.current).add_dir(self.facing) next = coords(self.current, self.facing) if not self.cell(next): self.set_cell(next, Cell()) self.cell(next).add_dir(OPP[self.facing]) self.current = next else: self.facing = {'L':LEFT, 'R':RIGHT}[char][self.facing] def walk_ahead(self, str): self.start = (0, 0) self.set_cell(self.start, Cell()) self.cell(self.start).add_dir(N) self.walk(str, self.start) self.end = self.current self.cell(self.end).add_dir(self.facing) return self def walk_back(self, str): self.facing = OPP[self.facing] self.walk(str, self.end) return self def __str__(self): keys = self.grid.keys() def coord_cmp(one, two): # If a y coord is lower, it has to be first if one[1] < two[1]: return -1 # if ys are equal, compare the xs if one[1] == two[1]: return cmp(one[0], two[0]) return 1 keys.sort(coord_cmp) min_x, min_y = keys[0] max_x, max_y = keys[-1] ret = [] for i in range(min_y, max_y+1): ret_row = [] for j in range(min_x, max_x+1): ret_row.append(self.grid[(j, i)].code()) ret.append(''.join(ret_row)) return '\n'.join(ret) def process_line(line): red_s, black_s = line.split() return str(Maze().walk_ahead(red_s).walk_back(black_s)) i = 1 try: f = open(sys.argv[1]) f.readline() #drop first for line in f.xreadlines(): print 'Case #%d:'%i print process_line(line) i += 1 except IndexError: print "USE: python maze.py "