Пример #1
0
class Solver(ABC):
    def __init__(self, sequence):
        self.sequence = sequence  # The sequence of the colors
        self.faces = Faces()  # Datastructure to model the color constraint
        self.partial = dict()  # Contains the partial solutions
        self.solutions = 0
        self.steps = 0

    @property
    @abstractmethod
    def starting_points():
        pass

    def solve(self):
        """ Start solving from every start point """
        for coord in self.starting_points:
            self._solve(coord, 0)
        return self.solutions, self.steps

    def _solve(self, coordinate, depth):
        """ Recursive step """
        # Condition for termination: The cube is completed
        if depth == len(self.sequence) - 1:
            self.solution()
            return True
        self.steps += 1
        color = self.sequence[depth]
        if self.constraints(coordinate, color):
            self.push(coordinate, color, depth)
            # Recursively solve for every neighbor
            for neighbor in neighbors(coordinate):
                if neighbor not in self.partial:  # Only use free spaces
                    self._solve(neighbor, depth + 1)
            self.pop(coordinate, color)

    def push(self, coordinate, color, depth):
        """ Step in: Go forward in the sequence and add the step to partial solution """
        self.partial[coordinate] = (color, depth)
        self.faces.push(coordinate, color)

    def pop(self, coordinate, color):
        """ Step out: Go backwards in the sequence and remove the step from the partial solution """
        self.faces.pop(coordinate, color)
        del self.partial[coordinate]

    def solution(self):
        """ Is called when a solution is found """
        self.solutions += 1
        human(self.partial)

    @abstractmethod
    def constraints(self, coordinate, color):
        """ Run checks to limit the recursion """
        return True