Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
 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"])
Exemplo n.º 7
0
    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')
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
 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)
Exemplo n.º 10
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 + \
Exemplo n.º 11
0
    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 = \
Exemplo n.º 12
0
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
Exemplo n.º 13
0
def test_cipic_hrir():
    hrir = CIPIC_HRIR('hrtfs/cipic_subj3')
    hrir.get_closest(Position(7 * pi / 4, -pi / 4, 3, 'polar'))
Exemplo n.º 14
0
 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(),
     }