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 if a solution exists, None otherwise
10 """
11 # Edge Case: Empty or None puzzle
12 if not puzzle:
13 return None
14
15 # Parse the puzzle to identify operators and operands
16 # First, normalize the equation
17 normalized = puzzle.replace("==", "=").replace(" ", "")
18
19 # Split by equals sign
20 parts = normalized.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 # Parse left side to identify operators and operands
27 left_side = parts[0]
28 right_side = parts[1]
29
30 # Identify the operator and split operands
31 if "*" in left_side:
32 operands = left_side.split("*")
33 operator = "*"
34 elif "-" in left_side:
35 operands = left_side.split("-")
36 operator = "-"
37 else: # Default to addition
38 operands = left_side.split("+")
39 operator = "+"
40
41 # Edge Case: No operands
42 if not operands:
43 return None
44
45 # Extract all unique letters (only alphabetic characters)
46 letters = set()
47 for part in operands + [right_side]:
48 for char in part:
49 if char.isalpha():
50 letters.add(char)
51
52 # Edge Case: No letters in puzzle
53 if not letters:
54 return None
55
56 # Extract first letters of multi-digit words (can't be zero)
57 first_letters = set()
58 for part in operands + [right_side]:
59 if part and part[0].isalpha() and len(part) > 1:
60 first_letters.add(part[0])
61
62 # Edge Case: More than 10 unique letters (impossible to solve)
63 if len(letters) > 10:
64 return None
65
66 letters = list(letters)
67
68 # Generate all possible digit assignments
69 from itertools import permutations
70
71 # Try all permutations of digits for the letters
72 for perm in permutations(range(10), len(letters)):
73 mapping = dict(zip(letters, perm))
74
75 # Edge Case: Leading zero in any word
76 if any(mapping.get(first, 0) == 0 for first in first_letters):
77 continue
78
79 # Calculate values of operands
80 operand_values = []
81 for operand in operands:
82 # If operand is a pure number, use it directly
83 if operand.isdigit():
84 operand_values.append(int(operand))
85 else:
86 # Calculate value from letters
87 value = 0
88 for char in operand:
89 if char.isalpha():
90 value = value * 10 + mapping[char]
91 else: # Handle case where operand might have digits
92 value = value * 10 + int(char)
93 operand_values.append(value)
94
95 # Calculate value of right side
96 if right_side.isdigit():
97 right_value = int(right_side)
98 else:
99 right_value = 0
100 for char in right_side:
101 if char.isalpha():
102 right_value = right_value * 10 + mapping[char]
103 else: # Handle case where right side might have digits
104 right_value = right_value * 10 + int(char)
105
106 # Check if equation is satisfied based on operator
107 if operator == "+":
108 if sum(operand_values) == right_value:
109 return mapping
110 elif operator == "-":
111 # For subtraction, we assume format like "AB - C == D"
112 if len(operand_values) == 2 and operand_values[0] - operand_values[1] == right_value:
113 return mapping
114 elif operator == "*":
115 # For multiplication, we assume format like "AB * C == DE"
116 if len(operand_values) == 2 and operand_values[0] * operand_values[1] == right_value:
117 return mapping
118
119 # Edge Case: No solution found
120 return None
121# 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 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.