A.2.1

Finished
11def solve(puzzle: str) -> dict[str, int] | None:
2 pass
2 """
3 Solve an alphametics puzzle.
4
5 Args:
6 puzzle: A string representing the alphametics puzzle (e.g., "SEND + MORE == MONEY")
7
8 Returns:
9 A dictionary mapping letters to digits that solves the puzzle, or None if no solution exists.
10
11 Example:
12 >>> solve("SEND + MORE == MONEY")
13 {'S': 9, 'E': 5, 'N': 6, 'D': 7, 'M': 1, 'O': 0, 'R': 8, 'Y': 2}
14 """
15 # Edge Case: Empty or None puzzle
16 if not puzzle:
17 return None
18
19 # Parse the puzzle
20 parts = puzzle.replace("==", "=").replace(" ", "").split("=")
21
22 # Edge Case: Invalid puzzle format (no equals sign or too many parts)
23 if len(parts) != 2:
24 return None
25
26 right_side = parts[1]
27
28 # Determine the operation and parse left side accordingly
29 left_expression = parts[0]
30 if "*" in left_expression:
31 operands = left_expression.split("*")
32 operation = "multiply"
33 left_parts = [operand.strip() for operand in operands]
34 elif "-" in left_expression:
35 operands = left_expression.split("-")
36 operation = "subtract"
37 left_parts = [operand.strip() for operand in operands]
38 else: # Default to addition
39 operation = "add"
40 left_parts = left_expression.replace("+", " ").split()
41
42 # Edge Case: No terms on the left side
43 if not left_parts:
44 return None
45
46 # Extract all unique letters
47 letters = set()
48 for part in left_parts + [right_side]:
49 letters.update(part)
50
51 # Edge Case: No letters in puzzle
52 if not letters:
53 return None
54
55 # Extract first letters (can't be zero)
56 first_letters = {word[0] for word in left_parts + [right_side]}
57
58 letters = list(letters)
59
60 # Edge Case: More than 10 unique letters (impossible to assign unique digits)
61 if len(letters) > 10:
62 return None
63
64 # Generate all possible digit assignments
65 from itertools import permutations
66
67 # Try all permutations of digits for the letters
68 for perm in permutations(range(10), len(letters)):
69 mapping = dict(zip(letters, perm))
70
71 # Edge Case: Leading zero in any number
72 if any(mapping[first] == 0 for first in first_letters):
73 continue
74
75 # Calculate left side result based on operation
76 if operation == "add":
77 left_result = 0
78 for word in left_parts:
79 num = 0
80 for char in word:
81 num = num * 10 + mapping[char]
82 left_result += num
83 elif operation == "subtract":
84 # For subtraction, we subtract all terms after the first from the first term
85 left_result = 0
86 for i, word in enumerate(left_parts):
87 num = 0
88 for char in word:
89 num = num * 10 + mapping[char]
90 if i == 0:
91 left_result = num
92 else:
93 left_result -= num
94 elif operation == "multiply":
95 left_result = 1
96 for word in left_parts:
97 num = 0
98 for char in word:
99 num = num * 10 + mapping[char]
100 if left_result == 1 and len(left_parts) > 1:
101 left_result = num
102 else:
103 left_result *= num
104
105 # Calculate right side value
106 right_num = 0
107 for char in right_side:
108 right_num = right_num * 10 + mapping[char]
109
110 # Check if equation is satisfied
111 if left_result == right_num:
112 return mapping
113
114 # Edge Case: No valid solution found
115 return None
116
117# Handled Edge Cases: Empty or None puzzle, Invalid puzzle format, No terms on left side, No letters in puzzle, More than 10 unique letters, Leading zero in any number, No valid 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.