goodagent

Finished
1from itertools import permutations
2
3
14def solve(puzzle: str) -> dict[str, int] | None:
2 pass
5 """
6 Solve an alphametics puzzle.
7
8 Args:
9 puzzle (str): A string representing the alphametics puzzle (e.g., "SEND + MORE == MONEY")
10
11 Returns:
12 dict[str, int] | None: A dictionary mapping letters to digits that solves the puzzle,
13 or None if no solution exists.
14
15 Example:
16 >>> solve("SEND + MORE == MONEY")
17 {'S': 9, 'E': 5, 'N': 6, 'D': 7, 'M': 1, 'O': 0, 'R': 8, 'Y': 2}
18 """
19 # Edge Case: Empty or None puzzle
20 if not puzzle:
21 return None
22
23 # Parse the puzzle into parts
24 # Remove spaces and split by '=='
25 parts = puzzle.replace(" ", "").split("==")
26
27 # Edge Case: Invalid puzzle format (no == or incorrect number of parts)
28 if len(parts) != 2:
29 return None
30
31 left_side, right_side = parts[0], parts[1]
32
33 # Split left side by '+' to get addends
34 addends = left_side.split("+")
35
36 # Edge Case: No addends on left side
37 if not addends or not all(addends):
38 return None
39
40 # Edge Case: Empty right side
41 if not right_side:
42 return None
43
44 # Collect all unique letters
45 unique_letters = set()
46 for part in addends + [right_side]:
47 unique_letters.update(part)
48
49 # Edge Case: No letters in puzzle
50 if not unique_letters:
51 return None
52
53 # Collect first letters (can't be zero)
54 first_letters = {word[0] for word in addends + [right_side]}
55
56 # Edge Case: More than 10 unique letters (impossible to assign unique digits)
57 if len(unique_letters) > 10:
58 return None
59
60 # Convert to list for consistent ordering
61 letters_list = list(unique_letters)
62
63 # Try all permutations of digits 0-9 for the unique letters
64 for perm in permutations(range(10), len(unique_letters)):
65 mapping = dict(zip(letters_list, perm))
66
67 # Edge Case: Leading zero in any word
68 if any(mapping[first_letter] == 0 for first_letter in first_letters):
69 continue
70
71 # Calculate the numerical values of the addends
72 addend_values = []
73 for addend in addends:
74 value = 0
75 for char in addend:
76 value = value * 10 + mapping[char]
77 addend_values.append(value)
78
79 # Calculate the numerical value of the result
80 result_value = 0
81 for char in right_side:
82 result_value = result_value * 10 + mapping[char]
83
84 # Check if the sum of addends equals the result
85 if sum(addend_values) == result_value:
86 return mapping
87
88 # Edge Case: No valid solution found
89 return None
90 # Handled Edge Cases: Empty/None puzzle, invalid format, no addends, empty right side,
91 # no letters, more than 10 unique letters, leading zeros, no solution found
Test NameStatus
test_leading_zero_solution_is_invalid
Pass
test_puzzle_with_eight_letters
Pass
test_puzzle_with_four_letters
Pass
test_puzzle_with_seven_letters
Pass
test_puzzle_with_six_letters
Pass
test_puzzle_with_ten_letters
Pass
test_puzzle_with_ten_letters_and_199_addends
Pass
test_puzzle_with_three_letters
Pass
test_puzzle_with_two_digits_final_carry
Pass
test_solution_must_have_unique_value_for_each_letter
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.