def evolve(active: List[Position], ndims: int = 4) -> List[Position]: """Evolves the board for 1 epoch. *ndims* can be 2, 3 or 4""" # Update the boundaries to add +2 positions on each dimension boundaries = get_boundaries(active) # Ignore higher dims than ndims if ndims <= 3: boundaries['w'] = (0, 1) if ndims <= 2: boundaries['z'] = (0, 1) new_active: List[Position] = [] # Check each position of the board, and on each dimension filter the active elements # to only consider those that within dist 1 on that dimension, therefore # significantly reducing the number of active elements to check for x in range(*boundaries['x']): near_x = [p for p in active if abs(p.x - x) <= 1] for y in range(*boundaries['y']): near_y = [p for p in near_x if abs(p.y - y) <= 1] for z in range(*boundaries['z']): near_z = [p for p in near_y if abs(p.z - z) <= 1] for w in range(*boundaries['w']): pos = Position(x, y, z, w) is_active = pos in near_z # Filter again on this dim to get the cound of neighbors iin all dims # Subtract 1 if this position is active, as it was also counted count = len([p for p in near_z if abs(p.w - w) <= 1 ]) - int(is_active) if (is_active and (count == 2 or count == 3)) or (not is_active and count == 3): new_active.append(pos) return new_active
def convert(day_input: List[str]) -> List[Position]: """Converts a board into a list of Positions""" active = [Position(x, y, 0) \ for y, line in enumerate(day_input) \ for x, c in enumerate(line) \ if c == '#'] return active
def solve_puzzle(puzzle: List[List[Optional[Tile]]], from_pos: Position, remaining: List[Tile]) -> bool: """Tries to solve the given *puzzle*, starting from *from_pos*, going left-to-right, top-to-bottom, with the *remaining* tiles. Modifies *puzzle* to reflect what could be done, as well as *remaining*""" if len(remaining) == 0: # The end return True # Get the left and top tile, and their edge ids that face this tile left_tile = puzzle[from_pos.y][from_pos.x - 1] if from_pos.x > 0 else None top_tile = puzzle[from_pos.y - 1][from_pos.x] if from_pos.y > 0 else None constraint_left = edges_after_ops(left_tile.edges, left_tile.stored_ops)[Tile.RIGHT] \ if left_tile is not None else None constraint_top = edges_after_ops(top_tile.edges, top_tile.stored_ops)[Tile.BOTTOM] \ if top_tile is not None else None # DFS, try each remaining tile, recusively calling us for each possible one for tile in remaining: ops = tile.is_compatible(constraint_left, constraint_top) if ops is not None: # Store the necessary ops to make the tile compatible tile.stored_ops = ops puzzle[from_pos.y][from_pos.x] = tile new_pos = Position((from_pos.x + 1) % len(puzzle), from_pos.y + (from_pos.x + 1) // len(puzzle)) if solve_puzzle(puzzle, new_pos, [t for t in remaining if t != tile]): return True return False
def solve_part_one(day_input: List[str]) -> int: pos = Position(0,0) facing = 'E' # Steps to take for each direction dirmap = {'N': Position(0, 1), 'S': Position(0, -1), 'E': Position(1, 0), 'W': Position(-1, 0)} rotations = ['N', 'E', 'S', 'W'] for inst in convert(day_input): if inst[0] in dirmap: # N,S,E,W pos += dirmap[inst[0]] * inst[1] elif inst[0] == 'F': # Move in the facing direction pos += dirmap[facing] * inst[1] else: # Rotate L or R, only works for multiples of 90 degrees turns = inst[1] // 90 d = 1 if inst[0] == 'R' else -1 # Rotate in the rotation array Left or Right facing = rotations[(rotations.index(facing) + d*turns) % len(rotations)] return manhattan_dist(pos)
def solve_part_two(day_input: List[str]) -> int: pos = Position(0,0) waypoint = Position(10, 1) dirmap = {'N': Position(0, 1), 'S': Position(0, -1), 'E': Position(1, 0), 'W': Position(-1, 0)} for inst in convert(day_input): if inst[0] in dirmap: # N,S,E,W, move the waypoint waypoint += dirmap[inst[0]] * inst[1] elif inst[0] == 'F': # Move in the waypoint direction pos += waypoint * inst[1] else: # Rotate turns = inst[1] // 90 d = 1 if inst[0] == 'R' else -1 # Move the waypoint around: R, change (x, y) to (y, -x); L, change (x, y) to (-y, x) for _ in range(turns): waypoint.x, waypoint.y = d * waypoint.y, -d * waypoint.x return manhattan_dist(pos)
def read_levels(self): for level_name, level in self.levels.items(): level.tileset = level.settings["tileset"] level.heightmap = level.settings["heightmap"] level.terrainmap = level.settings["terrainmap"] if "tile_width" in level.settings: level.tile_width = int(level.settings["tile_width"]) if game.settings.get('debug')['on']: debug(level.settings, "Loaded Level " + level_name) for object_name, object_settings in level.settings["gobjects"].items(): gobject_from_level_dict = game.add( gameobject.GameObject(object_name, Position(object_settings['position'][0], object_settings['position'][1]), Size(object_settings["size"][0], object_settings["size"][1]))) gobject_from_level_dict.chimg(object_settings["image"])
def __init__(self, dirname): elevation = np.array([ -45, -39, -34, -28, -23, -17, -11, -6, 0, 6, 11, 17, 23, 28, 34, 39, 45, 51, 56, 62, 68, 73, 79, 84, 90, 96, 101, 107, 113, 118, 124, 129, 135, 141, 146, 152, 158, 163, 169, 174, 180, 186, 191, 197, 203, 208, 214, 219, 225, 231 ]) azimuth = np.array([ -80, -65, -55, -45, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 45, 55, 65, 80 ]) self.right_hrir = np.zeros((200, len(azimuth), len(elevation))) self.left_hrir = np.zeros((200, len(azimuth), len(elevation))) for i, phi in enumerate(azimuth): right_fn = ('neg' if phi < 0 else '') + str( abs(phi)) + 'azright.wav' left_fn = ('neg' if phi < 0 else '') + str(abs(phi)) + 'azleft.wav' self.right_hrir[:, i, :] = np.flip(load_wav( os.path.join(dirname, right_fn))[0], axis=0) self.left_hrir[:, i, :] = np.flip(load_wav( os.path.join(dirname, left_fn))[0], axis=0) radius = 3. self.hrir_db = [] for i, az in enumerate(azimuth): for j, elev in enumerate(elevation): xp = radius * cos(elev * pi / 180.) * sin(az * pi / 180.) yp = radius * cos(elev * pi / 180.) * cos(az * pi / 180.) zp = radius * sin(elev * pi / 180.) x, y, z = yp, -xp, zp # x, y, z = xp, yp, zp p = Position(x, y, z, 'cartesian') self.hrir_db.append( (p, self.left_hrir[:, i, j], self.right_hrir[:, i, j])) self.kdt = KDTree(np.array([ hrir[0].coords('cartesian') / np.linalg.norm(hrir[0].coords('cartesian')) for hrir in self.hrir_db ]), leaf_size=2, metric='euclidean')
def draw_screen(self): if self.manages_levels: current_level = self.manages_levels.current_level self._display.fill( pygame.Color(current_level.settings["background_color"])) tiles = current_level.populated for i in range(0, len(tiles)): scale = self.settings.get('screen')['scale'] position = Position( current_level.tile_width * scale * i, self.settings.get('levels')["default_height"] + -10 * tiles[i].height) size = Size(current_level.tile_width * scale, 300) tile_sprite = current_level.terrains[tiles[i].terrain] self._display.blit( tile_sprite, pygame.Rect(position.x, position.y, size.width, size.height)) else: self._display.fill(pygame.Color("black")) for name, game_object in self.game_objects.items(): self._display.blit(game_object.image, game_object.rect)
def size_and_position(): self.position = position if position is not None else Position(0, 0) self.size = size if size is not None else Size(0, 0)
VisTag = CaselessKeyword('vis').setParseAction(replaceWith(True))('visible') UnvisTag = CaselessKeyword('unvis').setParseAction(replaceWith(False))('visible') TrackMaterialParams = \ Group( FileName('tex') + \ DecimalNum('scale'))('rail') + \ Group( FileName('tex') + \ DecimalNum('height') + \ DecimalNum('width') + \ DecimalNum('slope'))('ballast') TrackMaterial = (VisTag + TrackMaterialParams('material')) | UnvisTag Point = Position.setResultsName('point', True) Roll = DecimalNum.setResultsName('roll', True) Control = Position.setResultsName('control', True) Radius = DecimalNum.setResultsName('radius', True) TrackGeometry = Point + Roll + Control + Control + Point + Roll + Radius SwitchGeometry = TrackGeometry + TrackGeometry Track = \ Preamble + \ TrackTag + \ CaselessKeyword('normal') + \ TrackPrefix + \ TrackMaterial + \ TrackGeometry('geometry') + \ TrackSuffix + \
CaselessKeyword('lights') + \ DecimalNum('delay') + \ Identifier('target') + \ OneOrMore(LightState)('state') + \ EndEventTag # animation event Animation = \ EventTag + \ Identifier('name') + \ CaselessKeyword('animation') + \ DecimalNum('delay') + \ Identifier('target') + \ oneOf('rotate translate', caseless=True)('kind') + \ Identifier('submodel') + \ Position('position') + \ DecimalNum('speed') + \ EndEventTag # track velocity event TrackVel = \ EventTag + \ Identifier('name') + \ CaselessKeyword('trackvel') + \ DecimalNum('delay') + \ Identifier('target') + \ DecimalNum('velocity') + \ EndEventTag # update values event UpdateValues = \
def solve_part_two(day_input: List[str]) -> int: tiles = convert(day_input) # Get first corner that has 2 edges not compatible with others corner = tiles[0] for tile in tiles: other_edges = list( flatten([ other.edges + other.edges_reversed() for other in tiles if other.key != tile.key ])) found = sum(edge in other_edges for edge in tile.edges) if found == 2: corner = tile break # Make it the top left on the puzzle idx = [i for i, edge in enumerate(corner.edges) if edge not in other_edges] if idx == [0, 1]: corner.stored_ops = [] elif idx == [1, 2]: corner.stored_ops = [Tile.ROTATE] * 3 elif idx == [2, 3]: corner.stored_ops = [Tile.ROTATE] * 2 elif idx == [0, 3]: corner.stored_ops = [Tile.ROTATE] puzzle_sz = int(sqrt(len(tiles))) # Create puzzle, put corner on corner and remove it from remaining puzzle: List[List[Optional[Tile]]] = [[None for _ in range(puzzle_sz)] for _ in range(puzzle_sz)] puzzle[0][0] = corner tiles.remove(corner) # Solve solved = solve_puzzle(puzzle, Position(1, 0), tiles) if not solved: return -1 # Join all images, without border, making sure that ops are applied img, i = [], 0 tile_sz = len(tiles[0].img_no_border()) for tile_line in puzzle: img += [''] * tile_sz for tile in tile_line: # type: ignore for j, l in enumerate( img_after_ops(tile.img_no_border(), tile.stored_ops)): img[i + j] += l i += tile_sz # Possible ways to rotate and flip the mask possible_ops = [ f + r for f in [[], [Tile.FLIP]] for r in [[Tile.ROTATE] * n for n in range(4)] ] #type: ignore for op in possible_ops: mask = img_after_ops([ " # ", "# ## ## ###", " # # # # # # " ], op) # Convolution, but using the mask coords, getting the start of the mask in img, if exists mask_coords = [(y, x) for y, line in enumerate(mask) for x, c in enumerate(line) if c == '#'] mask_starts = [(y, x) \ for y in range(len(img) - len(mask)) \ for x in range(len(img[0]) - len(mask[0])) \ if all([img[y + cy][x + cx] == '#' for cy, cx in mask_coords])] if len(mask_starts) > 0: return sum(l.count('#') for l in img) - len(mask_starts) * sum( l.count('#') for l in mask) return -1
def test_cipic_hrir(): hrir = CIPIC_HRIR('hrtfs/cipic_subj3') hrir.get_closest(Position(7 * pi / 4, -pi / 4, 3, 'polar'))
def __init__(self): self.map = { Position(0, 12): Floor(), Position(1, 12): Water(), Position(2, 12): Floor(), Position(3, 12): Floor(), Position(4, 12): Floor(), Position(5, 12): Floor(), Position(6, 12): Floor(), Position(7, 12): Floor(), Position(8, 12): Floor(), Position(9, 12): Floor(), Position(10, 12): Floor(), Position(11, 12): Floor(), Position(12, 12): Floor(), Position(0, 11): Water(), Position(1, 11): Floor(), Position(2, 11): Water(), Position(3, 11): Floor(), Position(4, 11): Floor(), Position(5, 11): Floor(), Position(6, 11): Floor(), Position(7, 11): Floor(), Position(8, 11): Floor(), Position(9, 11): Floor(), Position(10, 11): Floor(), Position(11, 11): Floor(), Position(12, 11): Floor(), Position(0, 10): Floor(), Position(1, 10): Water(), Position(2, 10): Floor(), Position(3, 10): Floor(), Position(4, 10): Floor(), Position(5, 10): Floor(), Position(6, 10): Floor(), Position(7, 10): Floor(), Position(8, 10): Floor(), Position(9, 10): Floor(), Position(10, 10): Floor(), Position(11, 10): Floor(), Position(12, 10): Floor(), Position(0, 9): Floor(), Position(1, 9): Floor(), Position(2, 9): Floor(), Position(3, 9): Floor(), Position(4, 9): Floor(), Position(5, 9): Floor(), Position(6, 9): Floor(), Position(7, 9): Floor(), Position(8, 9): Floor(), Position(9, 9): Floor(), Position(10, 9): Floor(), Position(11, 9): Floor(), Position(12, 9): Floor(), Position(0, 8): Floor(), Position(1, 8): Floor(), Position(2, 8): Floor(), Position(3, 8): Floor(), Position(4, 8): Floor(), Position(5, 8): Floor(), Position(6, 8): Floor(), Position(7, 8): Floor(), Position(8, 8): Floor(), Position(9, 8): Floor(), Position(10, 8): Floor(), Position(11, 8): Floor(), Position(12, 8): Floor(), Position(0, 7): Floor(), Position(1, 7): Floor(), Position(2, 7): Floor(), Position(3, 7): Floor(), Position(4, 7): Floor(), Position(5, 7): Floor(), Position(6, 7): Floor(), Position(7, 7): Floor(), Position(8, 7): Floor(), Position(9, 7): Floor(), Position(10, 7): Floor(), Position(11, 7): Floor(), Position(12, 7): Floor(), Position(0, 6): Floor(), Position(1, 6): Floor(), Position(2, 6): Floor(), Position(3, 6): Floor(), Position(4, 6): Floor(), Position(5, 6): Floor(), Position(6, 6): Floor(), Position(7, 6): Floor(), Position(8, 6): Floor(), Position(9, 6): Floor(), Position(10, 6): Floor(), Position(11, 6): Floor(), Position(12, 6): Floor(), Position(0, 5): Floor(), Position(1, 5): Floor(), Position(2, 5): Floor(), Position(3, 5): Floor(), Position(4, 5): Floor(), Position(5, 5): Floor(), Position(6, 5): Floor(), Position(7, 5): Floor(), Position(8, 5): Floor(), Position(9, 5): Floor(), Position(10, 5): Floor(), Position(11, 5): Floor(), Position(12, 5): Floor(), Position(0, 4): Floor(), Position(1, 4): Floor(), Position(2, 4): Floor(), Position(3, 4): Floor(), Position(4, 4): Floor(), Position(5, 4): Floor(), Position(6, 4): Floor(), Position(7, 4): Floor(), Position(8, 4): Floor(), Position(9, 4): Floor(), Position(10, 4): Floor(), Position(11, 4): Floor(), Position(12, 4): Floor(), Position(0, 3): Floor(), Position(1, 3): Floor(), Position(2, 3): Floor(), Position(3, 3): Floor(), Position(4, 3): Floor(), Position(5, 3): Floor(), Position(6, 3): Floor(), Position(7, 3): Floor(), Position(8, 3): Floor(), Position(9, 3): Floor(), Position(10, 3): Floor(), Position(11, 3): Floor(), Position(12, 3): Floor(), Position(0, 2): Water(), Position(1, 2): Water(), Position(2, 2): Water(), Position(3, 2): Floor(), Position(4, 2): Floor(), Position(5, 2): Floor(), Position(6, 2): Floor(), Position(7, 2): Floor(), Position(8, 2): Floor(), Position(9, 2): Floor(), Position(10, 2): Floor(), Position(11, 2): Floor(), Position(12, 2): Floor(), Position(0, 1): Water(), Position(1, 1): Floor(), Position(2, 1): Water(), Position(3, 1): Floor(), Position(4, 1): Floor(), Position(5, 1): Floor(), Position(6, 1): Floor(), Position(7, 1): Floor(), Position(8, 1): Floor(), Position(9, 1): Floor(), Position(10, 1): Floor(), Position(11, 1): Floor(), Position(12, 1): Floor(), Position(0, 0): Water(), Position(1, 0): Water(), Position(2, 0): Water(), Position(3, 0): Floor(), Position(4, 0): Floor(), Position(5, 0): Floor(), Position(6, 0): Floor(), Position(7, 0): Floor(), Position(8, 0): Floor(), Position(9, 0): Floor(), Position(10, 0): Floor(), Position(11, 0): Water(), Position(12, 0): Floor(), }