Konoha

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 The function uses backtracking to try different digit assignments for letters, respecting:
12 - Each letter maps to a unique digit
13 - Leading digits cannot be zero
14 - The mathematical equation must be satisfied
15 """
16 # Edge Case: Empty or None puzzle
17 if not puzzle:
18 return None
19
20 # Parse the puzzle
21 parts = puzzle.replace("==", "=").replace(" ", "").split("=")
22
23 # Edge Case: Invalid puzzle format (no equals sign or too many parts)
24 if len(parts) != 2:
25 return None
26
27 left_side, right_side = parts[0], parts[1]
28
29 # Extract all terms (numbers being added)
30 terms = left_side.replace("+", " ").split()
31
32 # Edge Case: No terms on the left side
33 if not terms:
34 return None
35
36 # Get all unique letters in the puzzle
37 letters = set()
38 for term in terms + [right_side]:
39 letters.update(term)
40
41 # Edge Case: No letters in puzzle
42 if not letters:
43 return None
44
45 # Get leading letters (first letter of each term)
46 leading_letters = {term[0] for term in terms + [right_side]}
47
48 # Convert to lists for indexing
49 letters = list(letters)
50
51 # Edge Case: More than 10 unique letters (impossible to assign unique digits)
52 if len(letters) > 10:
53 return None
54
55 # Try all possible digit assignments using backtracking
56 def backtrack(index, used_digits, letter_to_digit):
57 """
58 Recursively try digit assignments for letters.
59
60 Args:
61 index: Current letter index we're assigning a digit to
62 used_digits: Set of digits already assigned
63 letter_to_digit: Current mapping of letters to digits
64
65 Returns:
66 A valid letter-to-digit mapping if found, otherwise None
67 """
68 # Base case: All letters have been assigned digits
69 if index == len(letters):
70 # Check if the equation is satisfied
71 # Convert terms to numbers
72 try:
73 term_values = []
74 for term in terms:
75 num = 0
76 for char in term:
77 num = num * 10 + letter_to_digit[char]
78 term_values.append(num)
79
80 # Convert result to number
81 result_value = 0
82 for char in right_side:
83 result_value = result_value * 10 + letter_to_digit[char]
84
85 # Check if equation holds
86 if sum(term_values) == result_value:
87 return letter_to_digit.copy()
88 except KeyError:
89 # This shouldn't happen if we've assigned all letters, but just in case
90 return None
91
92 return None
93
94 # Try assigning each unused digit to the current letter
95 current_letter = letters[index]
96
97 for digit in range(10):
98 # Skip if digit is already used
99 if digit in used_digits:
100 continue
101
102 # Skip if assigning 0 to a leading letter
103 if digit == 0 and current_letter in leading_letters:
104 continue
105
106 # Try this assignment
107 letter_to_digit[current_letter] = digit
108 used_digits.add(digit)
109
110 # Recurse to the next letter
111 result = backtrack(index + 1, used_digits, letter_to_digit)
112 if result is not None:
113 return result
114
115 # Backtrack
116 used_digits.remove(digit)
117 del letter_to_digit[current_letter]
118
119 return None
120
121 # Start the backtracking process
122 solution = backtrack(0, set(), {})
123 return solution
124
125# Handled Edge Cases: Empty/None puzzle, invalid puzzle format, no terms on left side, no letters in puzzle, more than 10 unique letters
126# Handled Edge Cases: All letters assigned, equation validation, leading zero constraint, digit uniqueness constraint
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.