Exemple #1
0
 def test() -> None:
     # For testing this class on its own, without needing OuterSolver
     locations = Clues.get_locations_from_grid(GRID)
     clue_list = Clues.create_from_text(ACROSS, DOWN, locations)
     solution = {
         'H': 1,
         'E': 2,
         'S': 3,
         'N': 4,
         'I': 5,
         'G': 6,
         'L': 7,
         'R': 8,
         'T': 9,
         'D': 10,
         'A': 11,
     }
     letter_values = {
         Letter(letter): value
         for letter, value in solution.items()
     }
     # Evaluate each of the clues
     clue_values = {
         clue: clue.evaluators[0](letter_values)
         for clue in clue_list
     }
     solver = InnerSolver(clue_list, clue_values, letter_values)
     solver.solve(debug=False)
Exemple #2
0
def run() -> None:
    locations = Clues.get_locations_from_grid(LOCATIONS)
    clue_list = Clues.create_from_text(ACROSS, DOWN, locations)
    solver = EquationSolver(clue_list,
                            items=tuple(range(1, 17)),
                            allow_duplicates=True)
    solver.verify_is_four_fold_symmetric()
    solver.solve()
Exemple #3
0
def create_clue_list(alt: bool = False) -> Sequence[Clue]:
    locations = Clues.get_locations_from_grid(GRID)
    result: List[Clue] = []
    for lines, is_across, letter in ((ACROSS, True, 'a'), (DOWN, False, 'd')):
        for line in lines.splitlines():
            line = line.strip()
            if not line:
                continue
            match = re.fullmatch(r'(\d+) (.*) \((\d+)\)', line)
            assert match
            number = int(match.group(1))
            expression = match.group(2)
            location = locations[number - 1]
            if '”' in expression:
                if alt:
                    expression = '+'.join(f'str({ch})' for ch in expression[1:-1])
                    expression = f'@ int({expression})'
                    clue = Clue(f'{number}{letter}', is_across, location, int(match.group(3)), expression=expression)
                    result.append(clue)
                else:
                    for ch in expression[1:-1]:
                        length = 1 if ch in 'TOM' else 2
                        clue = Clue(f'{number}{ch}{letter}', is_across, location, length, expression=ch)
                        result.append(clue)
                        (row, column) = location
                        location = (row, column + length) if is_across else (row + length, column)
            else:
                if not alt and number == 47:
                    clue = Clue(f'{number}{letter}', is_across, location, int(match.group(3)))
                elif not alt and number in (5, 15, 16):
                    continue
                else:
                    clue = Clue(f'{number}{letter}', is_across, location, int(match.group(3)), expression=expression)
                result.append(clue)
    return result
Exemple #4
0
    def make_clue_list(self) -> Sequence[Clue]:
        locations = Clues.get_locations_from_grid(GRID)
        clues = []
        for lines, is_across, letter in ((ACROSS, True, 'a'), (DOWN, False,
                                                               'd')):
            for line in lines.splitlines():
                line = line.strip()
                if not line:
                    continue
                match = re.fullmatch(r'(\d+) (.*) \((\d+)\)', line)
                assert match
                number = int(match.group(1))
                equation = match.group(2)
                length = int(match.group(3))
                location = locations[number - 1]

                # Put an exponent (e.g. **a, **b, **c) after each number.
                def replacer(xmatch: Match[str]) -> str:
                    variable = chr(xmatch.end(0) + ord('A'))
                    return xmatch.group(0) + '**' + variable

                equation = re.sub(r'(\d+)', replacer, equation)
                clue = Clue(f'{number}{letter}',
                            is_across,
                            location,
                            length,
                            expression=equation,
                            generator=self.generator)
                clues.append(clue)
        return clues
Exemple #5
0
def make_clue_list() -> Sequence[Clue]:
    locations = Clues.get_locations_from_grid(
        GRID)  # first location is index 0
    clues = [
        Clue(str(i), i in ACROSSES, locations[i - 1], LENGTHS[i])
        for i in range(1, len(LENGTHS))
    ]
    return clues
def make_clue_list() -> Sequence[Clue]:
    locations = Clues.get_locations_from_grid(GRID)
    clues = []
    for (is_across, clue_info, suffix) in (True, ACROSS, 'a'), (False, DOWN, 'd'):
        for name, length, generator, in clue_info:
            generator = generator or all_values
            clue = Clue(name + suffix, is_across, locations[int(name, 16) - 1], length, generator=generator)
            clues.append(clue)
    return clues
Exemple #7
0
 def run() -> None:
     grid = Clues.get_locations_from_grid(GRID)
     clues = OuterSolver.create_from_text(ACROSS, DOWN, grid)
     solver = OuterSolver(clues)
     for clue in clues:
         if clue.name in ('8d', '24d', '29d'):
             solver.add_constraint([clue],
                                   lambda value: value == value[::-1])
         else:
             solver.add_constraint([clue],
                                   lambda value: value != value[::-1])
     solver.solve(debug=True)
Exemple #8
0
def make_clue_list(
        lines: str, acrosses: Sequence[Tuple[int, int, ClueValueGenerator]],
        downs: Sequence[Tuple[int, int, ClueValueGenerator]]) -> List[Clue]:
    locations = Clues.get_locations_from_grid(lines)
    clues = [
        Clue(f'{location}{suffix}',
             is_across,
             locations[location - 1],
             length,
             generator=generator)
        for is_across, suffix, clue_set in ((True, 'a', acrosses), (False, 'd',
                                                                    downs))
        for (location, length, generator) in clue_set
    ]
    return clues
Exemple #9
0
 def test() -> None:
     letters = (('A', 3), ('T', 7), ('K', 18), ('V', 17), ('B', 10),
                ('R', 5), ('N', 9), ('L', 11), ('M', 19), ('E', 6),
                ('S', 1), ('I', 8), ('W', 13), ('G', 4), ('D', 15),
                ('C', 2), ('O', 14), ('U', 16), ('H', 12))
     print(', '.join(x for x, _ in letters), '=',
           ', '.join(str(x) for _, x in letters))
     letter_values = {Letter(letter): value for letter, value in letters}
     grid = Clues.get_locations_from_grid(GRID)
     clues = OuterSolver.create_from_text(ACROSS, DOWN, grid)
     clue_values: KnownClueDict = {
         clue: clue.evaluators[0](letter_values)
         for clue in clues
     }
     solver = InnerSolver(clues, clue_values, letter_values)
     solver.solve(debug=True)
Exemple #10
0
    def get_clue_list() -> Sequence[Clue]:
        grid_locations = Clues.get_locations_from_grid(GRID)

        def generator(clue: Clue) -> Sequence[int]:
            length = clue.length
            delta = cast(int, clue.context)
            return make_puzzle_table()[length, delta]

        clues = []
        for lines, is_across, letter in ((INUNDATION, True, 'i'),
                                         (HARVEST, False, 'h'), (PLANTING,
                                                                 False, 'p')):
            for line in lines.splitlines():
                line = line.strip()
                if not line:
                    continue
                match = re.fullmatch(r'(\d+) (\d+) \((\d+)\)', line)
                assert match
                number, delta, length = int(match.group(1)), int(
                    match.group(2)), int(match.group(3))
                (row, column) = grid_locations[number - 1]
                if letter == 'i':
                    locations = [(row, column + i) for i in range(length)]
                elif letter == 'h':
                    locations = [(row, column)]
                    while len(locations) < length:
                        row, column = (row, column -
                                       1) if column % 2 == 0 else (row - 1,
                                                                   column + 1)
                        locations.append((row, column))
                else:
                    locations = [(row, column)]
                    while len(locations) < length:
                        row, column = (row, column -
                                       1) if column % 2 == 1 else (row + 1,
                                                                   column - 1)
                        locations.append((row, column))
                clue = Clue(f'{number}{letter}',
                            is_across, (row, column),
                            length,
                            locations=locations,
                            context=delta,
                            generator=generator)
                clues.append(clue)
        return clues
    def get_clue_list() -> Sequence[Clue]:
        grid_locations = [None] + Clues.get_locations_from_grid(GRID)

        clues = [
            Clue("1a",
                 True,
                 grid_locations[1],
                 3,
                 generator=filtering(lambda x: factor_count(x) == 6)),
            Clue("3a", True, grid_locations[3], 2, generator=allvalues),
            Clue("5a",
                 True,
                 grid_locations[5],
                 2,
                 generator=filtering(
                     lambda x: factor_count(factor_sum(x)) == 15)),
            Clue("6a", True, grid_locations[6], 3, generator=allvalues),
            Clue("8a", True, grid_locations[8], 3, generator=allvalues),
            Clue("10a", True, grid_locations[10], 3, generator=allvalues),
            Clue("12a", True, grid_locations[12], 2, generator=allvalues),
            Clue("14a", True, grid_locations[14], 2, generator=allvalues),
            Clue("15a", True, grid_locations[15], 3, generator=allvalues),
            Clue("1d", False, grid_locations[1], 2, generator=allvalues),
            Clue("2d",
                 False,
                 grid_locations[2],
                 3,
                 generator=filtering(
                     lambda x: factor_count(factor_sum(x)) == 16)),
            Clue("3d", False, grid_locations[3], 2, generator=allvalues),
            Clue("4d", False, grid_locations[4], 3, generator=allvalues),
            Clue("6d", False, grid_locations[6], 3, generator=allvalues),
            Clue("7d", False, grid_locations[7], 3, generator=generators.cube),
            Clue("9d", False, grid_locations[9], 3, generator=allvalues),
            Clue("11d", False, grid_locations[11], 2, generator=allvalues),
            Clue("13d", False, grid_locations[13], 2, generator=allvalues),
        ]
        return clues
    def make_clue_list(self) -> Sequence[Clue]:
        def square_or_triangular(clue: Clue) -> Iterator[int]:
            yield from generators.square(clue)
            yield from generators.triangular(clue)

        locations = Clues.get_locations_from_grid(GRID)
        clues = [
            Clue('1a', True, locations[0], 3,
                 generator=generators.known(*[start for (start, _) in self.start_to_harshards.keys()])),
            Clue('2a', True, locations[1], 3, generator=generators.allvalues),
            Clue('4a', True, locations[3], 3, generator=square_or_triangular),
            Clue('8a', True, locations[7], 3, generator=square_or_triangular),
            Clue('9a', True, locations[8], 3, generator=generators.allvalues),
            Clue('10a', True, locations[9], 3, generator=generators.allvalues),
            Clue('1d', False, locations[0], 3, generator=generators.allvalues),
            Clue('3d', False, locations[2], 3, generator=generators.triangular),
            Clue('4d', False, locations[3], 3,
                 generator=generators.known(*[delta for (_, delta) in self.start_to_harshards.keys()])),
            Clue('5d', False, locations[4], 2, generator=generators.allvalues),
            Clue('6d', False, locations[5], 2, generator=generators.allvalues),
            Clue('7d', False, locations[6], 3, generator=generators.allvalues),
        ]
        return clues
Exemple #13
0
 def run() -> None:
     locations = Clues.get_locations_from_grid(GRID)
     clue_list = Clues.create_from_text(ACROSS, DOWN, locations)
     solver = OuterSolver(clue_list, items=range(1, 12))
     solver.verify_is_180_symmetric()
     solver.solve()
Exemple #14
0
 def make_clue_list(self) -> Sequence[Clue]:
     locations = Clues.get_locations_from_grid(GRID)
     return Clues.create_from_text(ACROSS, DOWN, locations)
Exemple #15
0
 def run() -> None:
     grid = Clues.get_locations_from_grid(GRID)
     clues = Clues.create_from_text(ACROSS, DOWN, grid)
     solver = OuterSolver(clues)
     solver.solve()
Exemple #16
0
 def run() -> None:
     locations = Clues.get_locations_from_grid(GRID)
     clue_list = Clues.create_from_text(ACROSS, DOWN, locations)
     solver = MySolver(clue_list, items=(2, 3, 5, 7, 11, 13, 4, 9, 25, 49, 121, 169))
     solver.verify_is_180_symmetric()
     solver.solve(debug=False)