Пример #1
0
def test_simple_collision():
    map_string = "#..#..#"
    asteroid_map = AsteroidMap.from_string(map_string)
    best_station_finder = BestStationFinder(asteroid_map)
    best_station_finder._remove_asteroids_not_seen_from(Coord(0, 0))

    assert best_station_finder._seen_by[Coord(0, 0)] == set([Coord(3, 0)])
Пример #2
0
    def get_boundaries(self):
        leftmost = min(coord.x for coord in self.color_values.keys())
        rightmost = max(coord.x for coord in self.color_values.keys())
        upmost = min(coord.y for coord in self.color_values.keys())
        bottommost = max(coord.y for coord in self.color_values.keys())

        return Coord(leftmost, upmost), Coord(rightmost, bottommost)
Пример #3
0
def test_more_granular():
    map_string, expected = case3()
    asteroid_map = AsteroidMap.from_string(map_string)
    best_station_finder = BestStationFinder(asteroid_map)

    best_station_finder._remove_asteroids_in_line_of(Coord(7, 3), Coord(7, 5))
    assert Coord(7, 6) not in best_station_finder._seen_by[Coord(7, 3)]
Пример #4
0
def test_correctly_count_painted_panels():
    canvas = Canvas()

    canvas.draw_at(Coord(42, 55), 1)
    canvas.draw_at(Coord(42, 55), 0)
    canvas.draw_at(Coord(1, 2), 1)

    assert canvas.count_painted_panels() == 2
Пример #5
0
    def __init__(self, asteroid_map, laser_position):
        self.asteroid_map = asteroid_map

        self.laser_position = laser_position
        self.laser_direction = Coord(0, -1)

        if self.laser_position in self.asteroid_map.asteroid_positions:
            self.asteroid_map.remove_asteroid(self.laser_position)
def test_disjoint_sets_have_no_intersection():
    wire1 = WireStub(set())
    wire2 = WireStub(set())

    wire1.points_visited.add(Coord(1, 2))
    wire2.points_visited.add(Coord(2, 3))

    with pytest.raises(IntersectionNotFoundError):
        find_closest_intersection(wire1, wire2)
Пример #7
0
def test_firing_laser_removes_hit_asteroid():
    asteroid_map = MagicMock()
    laser_position = Coord(3, 4)

    asteroid_map.all_asteroids_in_line_of = MagicMock(
        return_value=iter([Coord(42, 55)]))

    laser = Laser(asteroid_map, laser_position)

    laser.fire()

    asteroid_map.remove_asteroid.assert_called_with(Coord(42, 55))
Пример #8
0
def test_rotating_to_next_asteroid():
    ## Laser map:
    ## #.
    ## X#
    asteroid_map = AsteroidMap.from_string("##\n##")
    laser_position = Coord(0, 1)

    laser = Laser(asteroid_map, laser_position)

    laser.fire()
    laser.rotate_to_next_asteroid()

    assert laser.laser_direction == Coord(1, -1)
Пример #9
0
def test_laser_rotates_to_hit_next_thing():
    amap, laser_pos = laser_test()

    laser = Laser(amap, laser_pos)

    asteroid_hit = laser.fire()
    laser.rotate_to_next_asteroid()
    asteroid_hit = laser.fire()
    laser.rotate_to_next_asteroid()

    assert asteroid_hit == Coord(9, 0)

    asteroid_hit = laser.fire()

    assert asteroid_hit == Coord(9, 1)
Пример #10
0
    def __init__(self, instructions):
        self._points_visited = {}
        self.steps = 0
        self.current_pos = Coord(0, 0)
        self._points_visited[self.current_pos] = 0

        self.process_wire_instructions(instructions)
Пример #11
0
def case4():
    map_4 = """.#..##.###...#######
##.############..##.
.#.######.########.#
.###.#######.####.#.
#####.##.#.##.###.##
..#####..#.#########
####################
#.####....###.#.#.##
##.#################
#####.##.###..####..
..######..##.#######
####.##.####...##..#
.#####..#.######.###
##...#.##########...
#.##########.#######
.####.#.###.###.#.##
....##.##.###..#####
.#.#.###########.###
#.#.#.#####.####.###
###.##.####.##.#..##
"""
    best_4 = (Coord(11, 13), 210)

    return map_4, best_4
Пример #12
0
def test_first_thing_laser_shoots_is_correct():
    amap, laser_pos = laser_test()

    laser = Laser(amap, laser_pos)

    asteroid_hit = laser.fire()

    assert asteroid_hit == Coord(8, 1)
Пример #13
0
def test_robot_receives_draw_input_and_updates_canvas():
    canvas = MagicMock()
    computer = MagicMock()

    robot = Robot(computer, canvas)

    robot.read_command(42)

    canvas.draw_at.assert_called_once_with(Coord(0, 0), 42)
Пример #14
0
def laser_test():
    map_string = """.#....#####...#..
##...##.#####..##
##...#...#.#####.
..#.....#...###..
..#.#.....#....##
"""
    laser_pos = Coord(8, 3)

    return AsteroidMap.from_string(map_string), laser_pos
Пример #15
0
def read_grid(read_line=input):
    """Read the grid from an input (file or stdin)."""
    width, height = [int(i) for i in read_line().split()]
    areas = {}
    for row in range(height):
        areas.update(
            {Coord(row, column): int(n)
             for column, n in enumerate(read_line().split())
             if int(n) > 0})
    return Grid((height, width), areas)
Пример #16
0
def test_robot_receives_draw_then_turn_input_and_turns_and_moves_accordingly():
    canvas = MagicMock()
    computer = MagicMock()

    robot = Robot(computer, canvas)

    robot.read_command(42)
    robot.read_command(1)

    canvas.draw_at.assert_called_once_with(Coord(0, 0), 42)
    canvas.draw_at.reset_mock()
    assert robot.pos == Coord(1, 0)

    # Now might as well turn again a bit
    robot.read_command(55)
    robot.read_command(0)

    canvas.draw_at.assert_called_once_with(Coord(1, 0), 55)
    assert robot.pos == Coord(1, -1)
Пример #17
0
def find_intersection(wire1: WireReader, wire2: WireReader, key: callable):
    common_items = wire1.points_visited.intersection(wire2.points_visited)
    try:
        common_items.remove(Coord(0, 0))
    except KeyError:
        pass

    if not common_items:
        raise IntersectionNotFoundError
    else:
        return min(common_items, key=key)
Пример #18
0
def test_robot_passes_canvas_color_to_computer_input():
    canvas = MagicMock()
    computer = MagicMock()

    robot = Robot(computer, canvas)

    computer.input_src = robot.get_camera
    computer.read_input = Mock(side_effect=computer.input_src())

    computer.read_input()

    canvas.get.assert_called_once_with(Coord(0, 0))
Пример #19
0
    def plot(self, canvas):
        symbols = (self.symbol, self.space)
        if self.invert:
            symbols = (symbols[1], symbols[0])

        top_left, bottom_right = canvas.get_boundaries()

        for row in range(top_left.y, bottom_right.y + 1):
            for col in range(top_left.x, bottom_right.x + 1):
                item = canvas.get(Coord(col, row))
                print(f"{symbols[item]}", end="")
            print()
Пример #20
0
def case3():
    map_3 = """#.#...#.#.
.###....#.
.#....#...
##.#.#.#.#
....#.#.#.
.##..###.#
..#...##..
..##....##
......#...
.####.###.
"""
    best_3 = (Coord(1, 2), 35)

    return map_3, best_3
Пример #21
0
    def from_string(cls, map_string):
        rows = map_string.split("\n")

        asteroids = set()

        for row_pos, row in enumerate(rows):

            for col_pos, symbol in enumerate(row):
                if symbol == "#":
                    asteroids.add(Coord(col_pos, row_pos))
                elif symbol != ".":
                    raise ValueError("Invalid symbol in input")

        num_cols = len(rows[0])
        shape = (num_cols, len(rows))
        return cls(shape, asteroids)
Пример #22
0
class Laser:
    def __init__(self, asteroid_map, laser_position):
        self.asteroid_map = asteroid_map

        self.laser_position = laser_position
        self.laser_direction = Coord(0, -1)

        if self.laser_position in self.asteroid_map.asteroid_positions:
            self.asteroid_map.remove_asteroid(self.laser_position)

    def fire(self):
        try:
            asteroid_hit = next(
                self.asteroid_map.all_asteroids_in_line_of(
                    self.laser_position, self.laser_direction
                )
            )
        except StopIteration:
            raise NoAsteroidInLineOfFireException()

        self.asteroid_map.remove_asteroid(asteroid_hit)
        return asteroid_hit

    def rotate_to_next_asteroid(self):
        # Find smallest rotation from current position
        def angle_between_laser_and(asteroid):
            vector_to_asteroid = asteroid - self.laser_position
            return self.laser_direction.angle_with(vector_to_asteroid)

        asteroid_candidates = self.asteroid_map.asteroid_positions.difference(
            self.asteroid_map.all_asteroids_in_line_of(
                self.laser_position, self.laser_direction
            )
        )

        if asteroid_candidates:
            next_asteroid = min(
                asteroid_candidates, key=lambda x: angle_between_laser_and(x),
            )

        self.laser_direction = (next_asteroid - self.laser_position).normalized()
def test_equal_one_item_sets_intersect_at_that_item():
    wire1 = WireStub(set([Coord(1, 2)]))
    wire2 = WireStub(set([Coord(1, 2)]))

    assert find_closest_intersection(wire1, wire2) == Coord(1, 2)
def test_if_only_00_is_common_have_no_intersection():
    wire1 = WireStub(set([Coord(0, 0)]))
    wire2 = WireStub(set([Coord(0, 0)]))

    with pytest.raises(IntersectionNotFoundError):
        find_closest_intersection(wire1, wire2)
Пример #25
0
def case2():
    map_2 = "......#.#.\n#..#.#....\n..#######.\n.#.#.###..\n.#..#.....\n..#....#.#\n#..#....#.\n.##.#..###\n##...#..#.\n.#....####"
    best_2 = (Coord(5, 8), 33)

    return map_2, best_2
def test_actually_finds_smallest_intersection():
    wire1 = WireStub(set([Coord(0, 0), Coord(2, 3), Coord(1, 20), Coord(10, 0)]))
    wire2 = WireStub(set([Coord(0, 0), Coord(2, 3), Coord(10, 0), Coord(1, 20)]))

    assert find_closest_intersection(wire1, wire2) == Coord(2, 3)
Пример #27
0
def test_empty_canvas_is_zero_everywhere():
    canvas = Canvas()

    assert canvas.get(Coord(0, 0)) == 0
    assert canvas.get(Coord(42, 55)) == 0
Пример #28
0
from helpers import Coord

OFFSETS = {
    'R': Coord(1, 0),
    'U': Coord(0, 1),
    'L': Coord(-1, 0),
    'D': Coord(0, -1)
}


class WireReader:
    def __init__(self, instructions):
        self._points_visited = {}
        self.steps = 0
        self.current_pos = Coord(0, 0)
        self._points_visited[self.current_pos] = 0

        self.process_wire_instructions(instructions)

    def process_wire_instructions(self, instructions):
        for instruction in instructions:
            self.process_instruction(instruction)

    def process_instruction(self, instruction):
        direction, distance = parse_instruction(instruction)
        offset = OFFSETS[direction]
        for i in range(distance):
            self.do_single_step(offset)
            self.update_step_counter()

    def do_single_step(self, offset):
Пример #29
0
def test_if_we_draw_somewhere_it_will_be_that_color():
    canvas = Canvas()

    canvas.draw_at(Coord(42, 55), 1)

    assert canvas.get(Coord(42, 55)) == 1
Пример #30
0
def test_visiting_again_doesnt_update():
    reader = WireReader(['R2', 'L3'])
    assert reader.get_step_count(Coord(0, 0)) == 0
    assert reader.get_step_count(Coord(1, 0)) == 1
    assert reader.get_step_count(Coord(2, 0)) == 2
    assert reader.get_step_count(Coord(-1, 0)) == 5