예제 #1
0
def test_overlap_strategy(line, instructions, result_line):
    overlap_strategy = OverlapStrategy()

    input_line = CellsLine.parse_line(line)
    actual_result = overlap_strategy.solve(line=input_line, instructions=instructions)
    expected_result = CellsLine.parse_line(result_line)

    assert actual_result == expected_result
    if line != result_line:
        assert actual_result != input_line
예제 #2
0
def test_edge_strategy(line, instructions, result_line):
    edge_strategy = EdgeStrategy()

    input_line = CellsLine.parse_line(line)
    actual_result = edge_strategy.solve(line=input_line,
                                        instructions=instructions)
    expected_result = CellsLine.parse_line(result_line)

    assert actual_result == expected_result
    if line != result_line:
        assert actual_result != input_line
예제 #3
0
def test_sections_identification_strategy(line, instructions, result_line):
    sections_identification_strategy = SectionsIdentificationStrategy()

    input_line = CellsLine.parse_line(line)
    actual_result = sections_identification_strategy.solve(
        line=input_line, instructions=instructions)
    expected_result = CellsLine.parse_line(result_line)

    assert actual_result == expected_result
    if line != result_line:
        assert actual_result != input_line
def test_max_section_identifier_strategy(line, instructions, result_line):
    max_section_identifier_strategy = MaxSectionIdentifierStrategy()

    input_line = CellsLine.parse_line(line)
    actual_result = max_section_identifier_strategy.solve(
        line=input_line, instructions=instructions)
    expected_result = CellsLine.parse_line(result_line)

    assert actual_result == expected_result
    if line != result_line:
        assert actual_result != input_line
예제 #5
0
def test_parse_cells_line():
    assert CellsLine.parse_line("X__OOO_X") == CellsLine([
        CellMark.CROSSED,
        CellMark.EMPTY,
        CellMark.EMPTY,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.EMPTY,
        CellMark.CROSSED,
    ])
def test_gaps_filler_strategy(line, instructions, result_line):
    gaps_filler_strategy = GapsFillerStrategy()

    input_line = CellsLine.parse_line(line)
    actual_result = gaps_filler_strategy.solve(
        line=input_line, instructions=instructions
    )
    expected_result = CellsLine.parse_line(result_line)

    assert actual_result == expected_result
    if line != result_line:
        assert actual_result != input_line
예제 #7
0
 def solve_one_way(self, line: CellsLine,
                   instructions: List[int]) -> CellsLine:
     number_of_instructions = len(instructions)
     for instruction_index in range(number_of_instructions):
         end_index = self.get_end_index(line, instructions,
                                        instruction_index)
         start_index = self.get_start_index(line, instructions,
                                            instruction_index)
         if start_index > end_index:
             continue
         line.mark_inclusive(start_index, end_index, CellMark.FILLED)
     return line
예제 #8
0
def test_griddlers_board_get_rows_and_columns():
    board = GriddlersBoard(rows=2, columns=3)
    board[0, 0] = CellMark.FILLED
    board[0, 1] = CellMark.FILLED
    board[1, 0] = CellMark.CROSSED
    board[1, 2] = CellMark.FILLED

    assert str(board) == "OO_\nX_O"

    assert board.get_row(0) == CellsLine.parse_line("OO_")
    assert board.get_row(1) == CellsLine.parse_line("X_O")

    assert board.get_column(0) == CellsLine.parse_line("OX")
    assert board.get_column(1) == CellsLine.parse_line("O_")
    assert board.get_column(2) == CellsLine.parse_line("_O")
예제 #9
0
 def get_start_index(self, line: CellsLine, instructions: List[int],
                     instruction_index: int):
     inverted_index = self.get_end_index(
         line=line.inverse(),
         instructions=instructions[::-1],
         instruction_index=self.inverse_index(
             index=instruction_index, list_length=len(instructions)))
     return self.inverse_index(inverted_index, len(line))
예제 #10
0
def test_cells_line_contains():
    cells_line = CellsLine.parse_line("___OOO_O")
    assert CellMark.EMPTY in cells_line
    assert CellMark.FILLED in cells_line
    assert CellMark.CROSSED not in cells_line

    cells_line[1] = CellMark.CROSSED

    assert CellMark.CROSSED in cells_line
예제 #11
0
def test_cells_line_get_item():
    cells_line = CellsLine.parse_line("X__OOO_X")
    assert cells_line[0] == CellMark.CROSSED
    assert cells_line[1] == CellMark.EMPTY
    assert cells_line[2] == CellMark.EMPTY
    assert cells_line[3] == CellMark.FILLED
    assert cells_line[4] == CellMark.FILLED
    assert cells_line[5] == CellMark.FILLED
    assert cells_line[6] == CellMark.EMPTY
    assert cells_line[7] == CellMark.CROSSED
예제 #12
0
def test_cells_line_sections_after_set():
    cells_line = CellsLine.parse_line("X__OOO_X")
    cells_line[6] = CellMark.FILLED
    assert cells_line.sections == [
        CellsSection(start=0, end=0, mark=CellMark.CROSSED,
                     blocked_below=True),
        CellsSection(start=1, end=2, mark=CellMark.EMPTY, blocked_below=True),
        CellsSection(start=3, end=6, mark=CellMark.FILLED, blocked_above=True),
        CellsSection(start=7, end=7, mark=CellMark.CROSSED,
                     blocked_above=True),
    ]
예제 #13
0
def test_cells_line_is_completed():
    cell_line = CellsLine([
        CellMark.CROSSED,
        CellMark.CROSSED,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.CROSSED,
    ])
    assert cell_line.is_completed
예제 #14
0
def test_cells_line_to_str():
    cell_line = CellsLine([
        CellMark.CROSSED,
        CellMark.EMPTY,
        CellMark.EMPTY,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.FILLED,
        CellMark.EMPTY,
        CellMark.CROSSED,
    ])
    assert str(cell_line) == "X__OOO_X"
예제 #15
0
    def solve_one_way(self, line: CellsLine,
                      instructions: List[int]) -> CellsLine:
        filled_sections = line.filled_sections
        if len(filled_sections) != len(instructions):
            return line
        for i in range(0, len(filled_sections) - 1):
            section, next_section = filled_sections[i], filled_sections[i + 1]
            instruction, next_instruction = instructions[i], instructions[i +
                                                                          1]
            if not self.splitted_sections(
                    line=line,
                    section=section,
                    next_section=next_section,
                    instruction=instruction,
                    next_instruction=next_instruction,
            ):
                return line

        for i in range(0, len(filled_sections) - 1):
            section, next_section = filled_sections[i], filled_sections[i + 1]
            instruction, next_instruction = instructions[i], instructions[i +
                                                                          1]
            cross_start = section.end + instruction - section.length + 1
            cross_end = next_section.start - next_instruction + next_section.length - 1
            line.mark_inclusive(cross_start, cross_end, CellMark.CROSSED)
        first_section, last_section = filled_sections[0], filled_sections[-1]
        first_instruction, last_instruction = instructions[0], instructions[-1]
        first_cross_end = first_section.start - first_instruction + first_section.length - 1
        if 0 <= first_cross_end < first_section.start:
            line.mark_inclusive(0, first_cross_end, CellMark.CROSSED)
        last_cross_start = last_section.end + last_instruction - last_section.length + 1
        if last_section.end < last_cross_start < len(line):
            line.mark_inclusive(last_cross_start,
                                len(line) - 1, CellMark.CROSSED)
        return line
예제 #16
0
def test_cells_line_sections():
    assert CellsLine.parse_line("X_OX_OOO_X").sections == [
        CellsSection(start=0, end=0, mark=CellMark.CROSSED,
                     blocked_below=True),
        CellsSection(start=1, end=1, mark=CellMark.EMPTY, blocked_below=True),
        CellsSection(start=2, end=2, mark=CellMark.FILLED, blocked_above=True),
        CellsSection(start=3, end=3, mark=CellMark.CROSSED),
        CellsSection(start=4, end=4, mark=CellMark.EMPTY, blocked_below=True),
        CellsSection(start=5, end=7, mark=CellMark.FILLED),
        CellsSection(start=8, end=8, mark=CellMark.EMPTY, blocked_above=True),
        CellsSection(start=9, end=9, mark=CellMark.CROSSED,
                     blocked_above=True),
    ]
예제 #17
0
 def solve_one_way(self, line: CellsLine,
                   instructions: List[int]) -> CellsLine:
     if line.is_completed:
         return line
     first_empty_section = line.empty_sections[0]
     if (first_empty_section.start != 0
             and line[first_empty_section.start - 1] == CellMark.FILLED):
         return line
     number_of_known_instructions = len([
         section for section in line.filled_sections
         if section.end < first_empty_section.start
     ])
     remaining_instructions = instructions[number_of_known_instructions:]
     if len(remaining_instructions) == 0:
         return line
     first_remaining_instruction = remaining_instructions[0]
     min_remaining_instruction = min(remaining_instructions)
     remaining_sections = [
         section for section in line.sections
         if section.start >= first_empty_section.start
     ]
     fill_first_gap = True
     for i in range(len(remaining_sections)):
         section = remaining_sections[i]
         if section.mark == CellMark.FILLED:
             if not fill_first_gap:
                 continue
             fill_first_gap = False
             previous_section = remaining_sections[i - 1]
             if (previous_section.mark == CellMark.EMPTY
                     and previous_section.length <=
                     first_remaining_instruction):
                 line.mark_inclusive(
                     section.start, previous_section.start +
                     first_remaining_instruction - 1, CellMark.FILLED)
                 if section.blocked_above:
                     line.mark_inclusive(
                         section.end - first_remaining_instruction + 1,
                         section.end, CellMark.FILLED)
                     if section.end - first_remaining_instruction >= 0:
                         line[
                             section.end -
                             first_remaining_instruction] = CellMark.CROSSED
             continue
         if section.mark == CellMark.CROSSED:
             continue
         if not section.blocked:
             continue
         if section.length >= first_remaining_instruction:
             fill_first_gap = False
         if (section.length < min_remaining_instruction
                 or (fill_first_gap
                     and section.length < first_remaining_instruction)):
             line.mark_inclusive(section.start, section.end,
                                 CellMark.CROSSED)
     return line
예제 #18
0
def test_griddlers_board_set_column():
    board = GriddlersBoard(rows=2, columns=3)
    board.set_column(0, CellsLine.parse_line("OX"))

    assert str(board) == "O__\nX__"
예제 #19
0
def test_cells_line_mark_inclusive():
    cells_line = CellsLine.parse_line("X__OXO_X")
    cells_line.mark_inclusive(2, 5, CellMark.FILLED)
    assert cells_line == CellsLine.parse_line("X_OOOO_X")
예제 #20
0
 def get_column(self, column_index: int) -> CellsLine:
     return CellsLine([self[(j, column_index)] for j in range(self.rows)])
예제 #21
0
 def get_row(self, row_index: int) -> CellsLine:
     return CellsLine([self[(row_index, j)] for j in range(self.columns)])
예제 #22
0
def test_cells_line_filled_sections():
    assert CellsLine.parse_line("X_OOXO_X").filled_sections == [
        CellsSection(start=2, end=3, mark=CellMark.FILLED, blocked_above=True),
        CellsSection(start=5, end=5, mark=CellMark.FILLED, blocked_below=True),
    ]
예제 #23
0
def test_cells_line_empty_sections():
    assert CellsLine.parse_line("X__OXO_X").empty_sections == [
        CellsSection(start=1, end=2, mark=CellMark.EMPTY, blocked_below=True),
        CellsSection(start=6, end=6, mark=CellMark.EMPTY, blocked_above=True),
    ]
예제 #24
0
def test_slice_cells_line():
    cells_line = CellsLine.parse_line("X__OXO_X")
    assert cells_line[1:5] == CellsLine.parse_line("__OX")
예제 #25
0
 def solve(self, line: CellsLine, instructions: List[int]) -> CellsLine:
     line = self.solve_one_way(deepcopy(line), instructions)
     if not self.one_way:
         line = self.solve_one_way(line.inverse(),
                                   instructions[::-1]).inverse()
     return line
예제 #26
0
def test_cells_line_convert_to_list():
    assert list(CellsLine.parse_line("X__OOO_X")) == [
        CellMark.CROSSED, CellMark.EMPTY, CellMark.EMPTY, CellMark.FILLED,
        CellMark.FILLED, CellMark.FILLED, CellMark.EMPTY, CellMark.CROSSED
    ]
예제 #27
0
def test_cells_line_length():
    assert len(CellsLine.parse_line("X__OOO_X")) == 8
    assert len(CellsLine.parse_line("XX_X")) == 4
    assert len(CellsLine.parse_line("O")) == 1
    assert len(CellsLine.parse_line("")) == 0
예제 #28
0
def test_cells_line_inverse():
    cells_line = CellsLine.parse_line("X__OOO_X")
    assert cells_line.inverse() == CellsLine.parse_line("X_OOO__X")
예제 #29
0
def test_cells_line_set_item():
    cells_line = CellsLine.parse_line("X__OOO_X")
    cells_line[1] = CellMark.CROSSED
    assert cells_line == CellsLine.parse_line("XX_OOO_X")