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
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}")