sn62

Finished
11def solve(puzzle: str) -> dict[str, int] | None:
2 pass
2 """
3 Solve an alphametics puzzle.
4
5 Args:
6 puzzle (str): A string representing the alphametics puzzle (e.g., "SEND + MORE == MONEY")
7
8 Returns:
9 dict[str, int] | None: A dictionary mapping letters to digits that solves the puzzle,
10 or None if no solution exists
11
12 The function uses backtracking to try different digit assignments to letters,
13 respecting the constraints that each letter maps to a unique digit and no
14 leading digit can be zero.
15
16 Handled Edge Cases: Empty puzzle string, puzzle with no alphabetic characters,
17 puzzle with too many unique letters (>10), invalid puzzle format
18 """
19 # Edge Case: Empty puzzle string
20 if not puzzle:
21 return None
22
23 # Parse the puzzle into words
24 # Remove spaces and split by '==' to separate left and right sides
25 parts = puzzle.replace(" ", "").split("==")
26
27 # Edge Case: Invalid puzzle format (no '==' or more than one '==')
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 letters = set()
46 for part in addends + [right_side]:
47 for char in part:
48 if char.isalpha():
49 letters.add(char)
50
51 # Edge Case: No letters in puzzle
52 if not letters:
53 return None
54
55 # Edge Case: More than 10 unique letters (impossible to assign unique digits)
56 if len(letters) > 10:
57 return None
58
59 # Identify first letters (can't be zero)
60 first_letters = {word[0] for word in addends + [right_side] if word}
61
62 # Convert set to list for indexing
63 letters_list = list(letters)
64
65 def is_valid_solution(mapping):
66 """Check if the current mapping is a valid solution to the puzzle."""
67 # Check for leading zeros
68 for word in addends + [right_side]:
69 if len(word) > 1 and mapping[word[0]] == 0:
70 return False
71
72 # Calculate left side sum
73 left_sum = 0
74 for word in addends:
75 num = 0
76 for char in word:
77 num = num * 10 + mapping[char]
78 left_sum += num
79
80 # Calculate right side value
81 right_num = 0
82 for char in right_side:
83 right_num = right_num * 10 + mapping[char]
84
85 return left_sum == right_num
86
87 def backtrack(index, mapping, used_digits):
88 """Backtracking function to try digit assignments."""
89 # Base case: all letters have been assigned
90 if index == len(letters_list):
91 if is_valid_solution(mapping):
92 return mapping.copy()
93 return None
94
95 letter = letters_list[index]
96
97 # Try each digit from 0-9
98 for digit in range(10):
99 # Skip if digit already used
100 if digit in used_digits:
101 continue
102
103 # Skip if this is a first letter and digit is 0
104 if letter in first_letters and digit == 0:
105 continue
106
107 # Try this digit assignment
108 mapping[letter] = digit
109 used_digits.add(digit)
110
111 # Recurse to next letter
112 result = backtrack(index + 1, mapping, used_digits)
113 if result is not None:
114 return result
115
116 # Backtrack
117 del mapping[letter]
118 used_digits.remove(digit)
119
120 return None
121
122 # Start backtracking with empty mapping
123 solution = backtrack(0, {}, set())
124 return solution
125
126# Handled Edge Cases: Empty puzzle string, puzzle with no alphabetic characters,
127# puzzle with too many unique letters (>10), invalid puzzle format,
128# no addends on left side, empty right side
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.