Пример #1
0
    def solve_range(self):
        def comb(point, value):
            """Format how a value is shown at a given coordinate"""
            return intern(f'{point} {value}')

        values = ['W', 'B']
        all_coords = list(product(range(self.height), range(self.width)))

        for coord in all_coords:
            # Assign a "White" or "Black Box" value to each cell
            self.cnf += one_of(comb(coord, value) for value in values)

            # Rule: No two black squares are orthogonally adjacent.
            neighbor_coord = self.find_adjacency(coord)
            neighbor_dnf = [comb(coord, 'B')]
            for p in neighbor_coord:
                neighbor_dnf.append(comb(p, 'W'))
            self.cnf += from_dnf([neighbor_dnf, [comb(coord, 'W')]])

        for clue in self.clues:
            # for each clue (numbered cell), assign a valid permutation of black boxes
            permutation_len = len(clue.permutation_box)
            p_dnf = []
            for i in range(permutation_len):
                # different possible permutations for each clue
                temp = []
                for direction in clue.permutation_box[i].keys():
                    if clue.permutation_box[i][direction]:
                        temp.append(
                            comb(clue.permutation_box[i][direction], 'B'))

                for direction in clue.permutation_white[i].keys():
                    for cell in clue.permutation_white[i][direction]:
                        temp.append(comb(cell, 'W'))

                p_dnf.append(temp)

            # TODO: This from_dnf is so slow, maybe need some optimization
            self.cnf += from_dnf(p_dnf)

        possible_solution = solve_all(self.cnf)
        res = []
        for solution_facts in possible_solution:
            ans = deepcopy(self.board)
            box_list = []
            for fact_str in solution_facts:
                if fact_str[-1] == 'B':
                    row, col = eval(fact_str[:-2])
                    box_list.append((row, col))
                    ans[row][col] = 'B'

            if self.check_connectivity(box_list):
                # Rule: Verify the connectivity of all of the white cells
                res.append(deepcopy(ans))

        return res
Пример #2
0
def beside(value1, value2):
    'The values occur side-by-side: blends1 & cat2 | blends2 & cat1 ...'
    return from_dnf([(comb(value1, i), comb(value2, j))
                     for i, j in zip(houses, houses[1:])] +
                    [(comb(value2, i), comb(value1, j))
                     for i, j in zip(houses, houses[1:])])
Пример #3
0
def consecutive(value1, value2):
    'The values are in consecutive houses:  green1 & white2 | green2 & white3 ...'
    return from_dnf([(comb(value1, i), comb(value2, j))
                     for i, j in zip(houses, houses[1:])])
Пример #4
0
def same_house(value1, value2):
    'The two values occur in the same house:  brit1 & red1 | brit2 & red2 ...'
    return from_dnf([(comb(value1, i), comb(value2, i)) for i in houses])
Пример #5
0
 def as_cnf(self) -> List[Tuple[str]]:
     return sat_utils.from_dnf(
         [(comb(self.value1, i), comb(self.value2, j))
          for i, j in zip(self.houses, self.houses[3:])] +
         [(comb(self.value2, i), comb(self.value1, j))
          for i, j in zip(self.houses, self.houses[3:])])
Пример #6
0
 def as_cnf(self) -> List[Tuple[str]]:
     return sat_utils.from_dnf((comb(self.value1, i), comb(self.value2, j))
                               for i, j in product(self.houses, self.houses)
                               if i > j)
Пример #7
0
 def as_cnf(self) -> List[Tuple[str]]:
     return sat_utils.from_dnf(
         (comb(self.value1, i), comb(self.value2, i)) for i in self.houses)