Ejemplo n.º 1
0
    def step_many(self,
                  step_count: int,
                  debugger: Debugger = Debugger(enabled=False)):
        """
        >>> print("!" + Life.from_life_text(
        ...     ".#.#.#\\n"
        ...     "...##.\\n"
        ...     "#....#\\n"
        ...     "..#...\\n"
        ...     "#.#..#\\n"
        ...     "####..\\n"
        ... ).step_many(4).show())
        !......
        ......
        ..##..
        ..##..
        ......
        ......
        """
        current = self
        debugger.reset()
        for _ in debugger.stepping(range(step_count)):
            current = current.step()
            debugger.default_report_if()

        return current
Ejemplo n.º 2
0
    def add_rows(self,
                 count: int,
                 debugger: Debugger = Debugger(enabled=False)):
        """
        >>> print("!" + Minefield.from_rows_text('..^^.').add_rows(2).show())
        !..^^.
        .^^^^
        ^^..^
        >>> print("!" + Minefield.from_rows_text(
        ...     '.^^.^.^^^^').add_rows(9).show())
        !.^^.^.^^^^
        ^^^...^..^
        ^.^^.^.^^.
        ..^^...^^^
        .^^^^.^^.^
        ^^..^.^^..
        ^^^^..^^^.
        ^..^^^^.^^
        .^^^..^.^^
        ^^.^^^..^^
        """
        debugger.reset()
        total_target = len(self.rows) + count
        for _ in range(count):
            self.add_row()
            debugger.step()
            if debugger.should_report():
                debugger.default_report(
                    f"rows: {len(self.rows)}/{total_target}")

        return self
Ejemplo n.º 3
0
    def solve(
            self, node_set: 'NodeSetExtended',
            target: Point2D = Point2D.ZERO_POINT,
            debugger: Debugger = Debugger(enabled=False),
    ) -> List['NodeSetExtended']:
        stack = [node_set]
        previous_map: PreviousMap = {node_set: None}
        duplicate_count = 0
        debugger.reset()
        target_position_map = self.get_target_positions(node_set)
        debugger.reset()
        while debugger.step_if(stack):
            current_node_set = stack.pop(0)
            next_states = self.get_next_states(
                current_node_set, target_position_map)
            for next_node_set in next_states:
                if next_node_set in previous_map:
                    duplicate_count += 1
                    continue
                previous_map[next_node_set] = current_node_set
                if next_node_set.position == target:
                    return self.get_solution(next_node_set, previous_map)
                stack.append(next_node_set)

            if debugger.should_report():
                debugger.default_report(
                    f"stack: {len(stack)}, pruned: {duplicate_count}")

        raise Exception(f"Could not find solution")
 def get_next_password(
         self,
         debugger: Debugger = Debugger(enabled=False),
 ) -> 'Password':
     """
     >>> Password('abcdefgh').get_next_password()
     'abcdffaa'
     >>> Password('ghijklmn').get_next_password()
     'ghjaabcc'
     """
     debugger.reset()
     for password in debugger.stepping(self.get_next_password_candidates()):
         if password.is_valid():
             return password
         debugger.default_report_if(password)
    def step_many(
        self,
        sequence: str,
        step_count: int = 40,
        debugger: Debugger = Debugger(enabled=False)) -> str:
        """
        >>> LookAndSay().step_many("1", 5)
        '312211'
        """
        debugger.reset()
        result = sequence
        for step in debugger.stepping(range(step_count)):
            result = self.step(result)
            if debugger.should_report():
                debugger.default_report(f"step {step}/{step_count}")

        return result
    def step_many(self, step_count: Optional[int] = None,
                  debugger: Debugger = Debugger(enabled=False)):
        if step_count is None:
            steps = count()
        else:
            steps = range(step_count)
        debugger.reset()
        for _ in debugger.stepping(steps):
            self.step()
            if self.has_finished():
                break
            if debugger.should_report():
                debugger.default_report(
                    f"remaining: {len(self.get_remaining_positions())}, "
                    f"position: {self.position}")

        return self
 def get_lowest_index_with_zeros(
     self,
     start: int = 1,
     zero_count: int = 5,
     debugger: Debugger = Debugger(enabled=False)) -> int:
     """
     >>> Hasher("abcdef").get_lowest_index_with_zeros()
     609043
     >>> Hasher("pqrstuv").get_lowest_index_with_zeros()
     1048970
     """
     prefix = '0' * zero_count
     debugger.reset()
     for index in debugger.stepping(count(start)):
         if self.does_index_give_hash_prefix(index, prefix):
             return index
         debugger.default_report_if(index)
Ejemplo n.º 8
0
 def apply(
     self,
     matrix: Optional[MatrixT] = None,
     debugger: Debugger = Debugger(enabled=False)
 ) -> MatrixT:
     """
     >>> InstructionSet.from_instructions_text(
     ...     "turn on 0,0 through 999,999").apply().get_brightness_total()
     2000000
     """
     if matrix is None:
         matrix_class = self.get_matrix_class()
         matrix = matrix_class()
     debugger.reset()
     for instruction in debugger.stepping(self.instructions):
         instruction.apply(matrix)
         debugger.default_report_if()
     return matrix
Ejemplo n.º 9
0
    def apply_extended(
            self,
            state: Optional[StateExtended] = None,
            debugger: Debugger = Debugger(enabled=False),
    ) -> StateExtended:
        """
        >>> def check(instructions_text, state_values=None, program_counter=0):
        ...     _state = InstructionSetExtended\\
        ...         .from_instructions_text(instructions_text)\\
        ...         .apply_extended(StateExtended(
        ...             state_values or {}, program_counter))
        ...     # noinspection PyUnresolvedReferences
        ...     values = {
        ...         name: value
        ...         for name, value in _state.values.items()
        ...         if value
        ...     }
        ...     return values, _state.program_counter
        >>> check(
        ...     "cpy 2 a\\n"
        ...     "tgl a\\n"
        ...     "tgl a\\n"
        ...     "tgl a\\n"
        ...     "cpy 1 a\\n"
        ...     "dec a\\n"
        ...     "dec a\\n"
        ... )
        ({'a': 3}, 7)
        """
        if state is None:
            state = StateExtended()
        state.instructions = list(self.instructions)
        debugger.reset()
        while debugger.step_if(
                0 <= state.program_counter < len(state.instructions)):
            self.step(state)
            if debugger.should_report():
                debugger.default_report(
                    f"values: {state.values}, pc: {state.program_counter}")

        return state
Ejemplo n.º 10
0
 def get_min_house_number_with_at_least_present_count(
     self,
     min_present_count: int,
     debugger: Debugger = Debugger(enabled=False)
 ) -> int:
     """
     >>> Santa().get_min_house_number_with_at_least_present_count(100)
     6
     """
     max_present_count_seen = None
     debugger.reset()
     for house_number in debugger.stepping(count(1)):
         present_count = self.get_house_present_count(house_number)
         if present_count >= min_present_count:
             return house_number
         if max_present_count_seen is None \
                 or present_count > max_present_count_seen:
             max_present_count_seen = present_count
         if debugger.should_report():
             debugger.default_report(
                 f"max presents: {max_present_count_seen}"
                 f"/{min_present_count}")
 def get_all_possible_chains(
     self,
     start: str,
     prune: Optional[Callable[[str], bool]] = None,
     debugger: Debugger = Debugger(enabled=False),
 ) -> Iterable[Tuple[str, ...]]:
     """
     >>> list(MachineExtended().get_all_possible_chains(""))
     []
     >>> list(MachineExtended({'H': ['O']}).get_all_possible_chains("HH"))
     [('HH', 'OH'), ('HH', 'HO'), ('HH', 'OH', 'OO'), ('HH', 'HO', 'OO')]
     >>> list(MachineExtended({'H': ['O']}).get_all_possible_chains(
     ...     "HH", lambda step: step != 'HO'))
     [('HH', 'OH'), ('HH', 'OH', 'OO')]
     >>> list(MachineExtended({'H': ['OH']}).get_all_possible_chains(
     ...     "HH", lambda step: len(step) <= 4))
     [('HH', 'OHH'), ('HH', 'HOH'), ('HH', 'OHH', 'OOHH'),
         ('HH', 'OHH', 'OHOH'), ('HH', 'HOH', 'OHOH'), ('HH', 'HOH', 'HOOH')]
     >>> list(MachineExtended({'H': ['O'], 'O': ['H']})
     ...      .get_all_possible_chains("HH"))
     [('HH', 'OH'), ('HH', 'HO'), ('HH', 'OH', 'OO'), ('HH', 'HO', 'OO'),
         ('HH', 'OH', 'OO', 'HO'), ('HH', 'HO', 'OO', 'OH')]
     """
     stack = [(start, ())]
     debugger.reset()
     while stack:
         current, chain = stack.pop()
         next_chain = chain + (current, )
         for next_step in self.get_all_possible_next_steps(current):
             if next_step in next_chain:
                 continue
             if prune and not prune(next_step):
                 continue
             yield next_chain + (next_step, )
             stack.append((next_step, next_chain))
         if debugger.should_report():
             debugger.default_report(f"stack size: {len(stack)}, "
                                     f"end length: {len(next_chain[-1])}, "
                                     f"chain length: {len(next_chain)}")
 def find_paths(
         self,
         start: Point2D = Point2D(0, 0),
         finish: Point2D = Point2D(3, 3),
         debugger: Debugger = Debugger(enabled=False),
 ) -> Iterable[str]:
     if start == finish:
         yield ''
     stack = [('', Point2D(0, 0))]
     debugger.reset()
     path_count = 0
     largest_path = None
     while stack:
         path, position = stack.pop(0)
         path_door_states = self.get_path_door_states(path)
         for direction, door_is_open in path_door_states.items():
             if not door_is_open:
                 continue
             next_position = position.offset(direction.offset)
             if not self.is_position_valid(next_position):
                 continue
             next_path = f"{path}{direction.value}"
             if next_position == finish:
                 path_count += 1
                 largest_path = next_path
                 yield next_path
             else:
                 stack.append((next_path, next_position))
         debugger.step()
         if debugger.should_report():
             debugger.report(
                 f"Step: {debugger.step_count}, time: "
                 f"{debugger.pretty_duration_since_start}, stack: "
                 f"{len(stack)}, paths: {path_count}, largest path: "
                 f"{largest_path and len(largest_path)}, average speed: "
                 f"{debugger.step_frequency}, recent speed: "
                 f"{debugger.step_frequency_since_last_report}")