Beispiel #1
0
def make_clue_list(clue_map: ClueMap) -> Sequence[Clue]:
    def generator(clue_value: int) -> ClueValueGenerator:
        def result(_: Clue) -> Iterable[str]:
            values_list = [v for (v, _) in clue_map[clue_value]]
            for values in values_list:
                string = ''.join(map(str, values))
                for i in range(5):
                    temp = ''.join(string[i:] + string[:i])
                    yield temp
                    yield temp[::-1]

        return result

    clues = []
    for (letter,
         value), location in zip(ACROSS,
                                 itertools.product((1, 3, 5, 7, 9), (1, 5))):
        clues.append(
            Clue(letter.upper(),
                 True,
                 location,
                 5,
                 context=value,
                 generator=generator(value)))
    for (letter,
         value), location in zip(DOWNS,
                                 itertools.product((1, 5), (1, 3, 5, 7, 9))):
        clues.append(
            Clue(letter,
                 False,
                 location,
                 5,
                 context=value,
                 generator=generator(value)))
    return clues
Beispiel #2
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
Beispiel #3
0
 def get_clue_list() -> Sequence[Clue]:
     possibilities = ((3, 3), (2, 2, 2), (1, 2, 3), (1, 3, 2), (3, 1, 2), (3, 2, 1), (2, 1, 3), (2, 3, 1),
                      (1, 2, 1, 2), (2, 1, 2, 1), (1, 2, 2, 1))
     for rows in itertools.product(possibilities, repeat=3):
         acrosses: Dict[Tuple[int, int], int] = {}
         downs: Dict[Tuple[int, int], int] = {}
         for row, lengths in enumerate(rows, start=1):
             column = 1
             for length in lengths:
                 if length != 1:
                     acrosses[row, column] = length
                     downs[column, 7 - row] = length
                     acrosses[7 - row, 7 - column - (length - 1)] = length
                     downs[7 - column - (length - 1), row] = length
                 column += length
             assert column == 7
         number_to_clue_start = Solver212.verify_is_legal_grid(acrosses, downs)
         if number_to_clue_start:
             result = []
             for number, clue_start in number_to_clue_start.items():
                 if clue_start in acrosses:
                     result.append(Clue(f'{number}a', True, clue_start, acrosses[clue_start]))
                 if clue_start in downs:
                     result.append(Clue(f'{number}d', False, clue_start, downs[clue_start]))
             return result
     return ()
Beispiel #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
def make(name: str, base_location: Location, length: int,
         generator: ClueValueGenerator) -> Clue:
    return Clue(name,
                name[0] == 'A',
                base_location,
                length,
                generator=generators.using_current_base(generator))
Beispiel #6
0
def make(name: str, base_location: Location, length: int,
         generator: Optional[ClueValueGenerator]) -> Clue:
    return Clue(name,
                name[0] == 'A',
                base_location,
                length,
                generator=generator)
Beispiel #7
0
def make_clue_list() -> Sequence[Clue]:
    locations = {}
    for row, line in enumerate(MAP.split()):
        for column, item in enumerate(line):
            if item != '.':
                locations[item] = row + 1, column + 1
    clues = []
    for is_across, suffix, clue_info in ((True, 'a', ACROSS), (False, 'd',
                                                               DOWN)):
        for line in clue_info.split('\n'):
            if not line:
                continue
            match = re.fullmatch(
                r'([a-z])\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*',
                line)
            assert match
            letter = match.group(1)
            values = [int(match.group(i)) for i in range(2, 7)]
            length = int(match.group(7))
            location = locations[letter]
            clue = Clue(f'{letter}{suffix}',
                        is_across,
                        location,
                        length,
                        generator=generator(values))
            clues.append(clue)
    return clues
Beispiel #8
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
Beispiel #9
0
def make_expressions() -> Sequence[Clue]:
    clues = []
    for line in CLUES.splitlines():
        name = line[0]
        expression = line[2:]
        expression = re.sub(r"([A-Z])(\d)", r"(\1**\2)", expression)
        clue = Clue(name, True, (0, 0), 1, expression=expression)
        clues.append(clue)
    return tuple(clues)
Beispiel #10
0
def make(name: str, expression: str, num_letters: int, length: int,
         base_location: Location) -> 'Clue':
    return Clue(name,
                name.isupper(),
                base_location,
                length,
                context=expression,
                generator=my_generator(num_letters),
                expression=expression)
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
Beispiel #12
0
def make(name: str,
         length: int,
         base_location: Location,
         *,
         generator: Optional[ClueValueGenerator] = None) -> 'Clue':
    return Clue(name,
                name.isupper(),
                base_location,
                length,
                generator=generator or generators.allvalues)
Beispiel #13
0
def make_clue_list(info: str) -> Sequence[Clue]:
    clues = []
    for line in info.splitlines():
        if not line:
            continue
        match = re.fullmatch(r'(\d+) (\d) (.*)', line)
        assert match
        # We don't care about the location.  We just care about the length
        clue = Clue(match.group(1), True, (1, 1), int(match.group(2)), expression=match.group(3))
        clues.append(clue)
    return clues
Beispiel #14
0
    def run(entries: Sequence[ClueValue]) -> None:
        def generator(a_clue: Clue) -> Iterable[str]:
            return (entry for entry in entries if len(entry) == a_clue.length)

        clues = []
        for suffix, is_across, clue_info in (('a', True, ACROSS), ('d', False, DOWN)):
            for xy, length in clue_info:
                q, r = divmod(xy - 11, 10)
                clue = Clue(f'{xy}{suffix}', is_across, (q + 1, r + 1), length, generator=generator)
                clues.append(clue)
        solver = InnerSolver(clues)
        solver.solve()
Beispiel #15
0
 def create_from_text(across: str, down: str,
                      locations: Sequence[Location]) -> Sequence[Clue]:
     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+)\) \((\d+)\)', line)
             assert match
             number = int(match.group(1))
             location = locations[number - 1]
             clue = Clue(f'{number}{letter}',
                         is_across,
                         location,
                         int(match.group(3)),
                         expression=match.group(2))
             clue.context = int(match.group(4))
             result.append(clue)
     return result
Beispiel #16
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
Beispiel #17
0
def create_to_type_dict() -> Dict[str, AnswerType]:
    # Creates a map from legal entry values to the answer type of that entry.  Values are only allowed to belong
    # to one type.
    creator: Tuple[Tuple[AnswerType, ClueValueGenerator], ...] = (
        (AnswerType.Fibonacci, generators.fibonacci),
        (AnswerType.Square, generators.square),
        (AnswerType.Triangle, generators.triangular),
        (AnswerType.Prime, generators.prime),
        (AnswerType.Palindrome, generators.palindrome))
    items = [(length, answer_type, str(value))
             for length in (1, 2, 3) for answer_type, generator in creator
             for value in generator(Clue('fake', True, (1, 1), length))]
    # count the number of times each value appears in the list of items.
    counter = collections.Counter(value for _, _, value in items)
    # create a map from the value to the type of the value, for those values that are a member
    # of only one group.
    return {value: answer_type for (_, answer_type, value) in items if counter[value] == 1}
 def create(length_1a: int, length_4a: int, length_5a: int, length_2d: int, length_3d: int,
            location_5a: Location, grid: Optional[str] = None) -> "Solver204":
     clues = [
         Clue('1a', True, (1, 1), length_1a, generator=GENERATOR_1a),
         Clue('4a', True, (2, 1), length_4a, generator=GENERATOR_4a),
         Clue('5a', True, location_5a, length_5a, generator=GENERATOR_5a),
         Clue('2d', False, (1, 2), length_2d, generator=GENERATOR_2d),
         Clue('3d', False, (1, 3), length_3d, generator=GENERATOR_3d),
         Clue('4d', False, (2, 1), 2, generator=GENERATOR_4d)
     ]
     grid = grid or f'{length_1a}{length_4a}{length_5a}{length_2d}{length_3d}{location_5a[1]}'
     return Solver204(grid, clues)
Beispiel #19
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
Beispiel #20
0
def create_clue_list() -> Sequence[Clue]:
    locations = [(0, 0)]
    for row, line in enumerate(GRID.split()):
        for column, item in enumerate(line):
            if item == 'X':
                locations.append((row + 1, column + 1))

    result: List[Clue] = []
    for lines, is_across, suffix in ((ACROSS, True, 'a'), (DOWN, False, 'd'),
                                     (THROUGH, False, 't')):
        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))
            location = locations[number]
            expression = match.group(2)
            length = int(match.group(3))

            row, column = location
            if suffix == 'd':
                location_list = [(row + i, column) for i in range(length)]
            elif suffix == 't':
                location_list = [(row + 4 * i, column) for i in range(length)]
            elif suffix == 'a':
                temp = [(row, column + i) for i in range(length)]
                location_list = [(row + ((column - 1) // 4) * 4,
                                  ((column - 1) % 4) + 1)
                                 for (row, column) in temp]
            else:
                assert False

            clue = Clue(f'{number}{suffix}',
                        is_across,
                        location,
                        length,
                        expression=expression,
                        locations=location_list)
            result.append(clue)
    return result
Beispiel #21
0
def make_clue_list(lines: str, acrosses: str, downs: str) -> List[Clue]:
    locations = [(0, 0)]
    for row, line in enumerate(lines.split()):
        for column, item in enumerate(line):
            if item == 'X':
                locations.append((row + 1, column + 1))
    clues = []
    for is_across, suffix, clue_info in ((True, 'a', acrosses), (False, 'd',
                                                                 downs)):
        for line in clue_info.split('\n'):
            if not line:
                continue
            match = re.fullmatch(r'(\d+) (\d+)', line)
            assert match
            number = int(match.group(1))
            info = match.group(2)
            clue = Clue(f'{number}{suffix}',
                        is_across,
                        locations[number],
                        len(info),
                        generator=generators.known(*MY_TABLE[info]))
            clues.append(clue)
    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
Beispiel #23
0
 def make_clue_list(self) -> List[Clue]:
     known = [value for _, value in self.clue_primes]
     generator = generators.known(*known)
     return [
         Clue('a', True, (1, 2), 2, generator=generator),
         Clue('b', True, (1, 4), 2, generator=generator),
         Clue('c', True, (2, 1), 2, generator=generator),
         Clue('d', True, (2, 3), 3, generator=generator),
         Clue('e', True, (3, 2), 3, generator=generator),
         Clue('f', True, (4, 1), 3, generator=generator),
         Clue('g', True, (4, 4), 2, generator=generator),
         Clue('h', True, (5, 1), 2, generator=generator),
         Clue('i', True, (5, 3), 2, generator=generator),
         Clue('j', False, (1, 1), 2, generator=generator),
         Clue('k', False, (1, 2), 3, generator=generator),
         Clue('l', False, (1, 4), 2, generator=generator),
         Clue('m', False, (2, 3), 3, generator=generator),
         Clue('n', False, (2, 5), 2, generator=generator),
         Clue('o', False, (3, 1), 2, generator=generator),
         Clue('p', False, (3, 4), 3, generator=generator),
         Clue('q', False, (4, 2), 2, generator=generator),
         Clue('r', False, (4, 5), 2, generator=generator),
     ]
    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