sourdough

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 left_expression = parts[0]
28
29 # Edge Case: No terms on the left side
30 if not left_expression:
31 return None
32
33 # Extract all unique letters
34 letters = set()
35 for char in left_expression + right_side:
36 if char.isalpha():
37 letters.add(char)
38
39 # Edge Case: No letters in puzzle
40 if not letters:
41 return None
42
43 # Extract first letters (can't be zero)
44 # We need to parse the expression to find all terms
45 first_letters = set()
46
47 # Find all words in the expression
48 import re
49 words = re.findall(r'[A-Z]+', left_expression + "=" + right_side)
50 for word in words:
51 if word: # Non-empty word
52 first_letters.add(word[0])
53
54 # Convert letters to a list for indexing
55 letters_list = list(letters)
56
57 # Try all permutations of digits for the letters
58 from itertools import permutations
59
60 # Edge Case: More letters than digits (0-9)
61 if len(letters_list) > 10:
62 return None
63
64 for perm in permutations(range(10), len(letters_list)):
65 mapping = dict(zip(letters_list, perm))
66
67 # Edge Case: Leading zero
68 if any(mapping[letter] == 0 for letter in first_letters):
69 continue
70
71 # Evaluate the left side expression
72 try:
73 # Replace letters with digits in the expression
74 left_expr_eval = left_expression
75 for letter, digit in mapping.items():
76 left_expr_eval = left_expr_eval.replace(letter, str(digit))
77
78 # Evaluate the expression
79 left_value = eval(left_expr_eval)
80
81 # Calculate right side value
82 right_number = 0
83 for letter in right_side:
84 right_number = right_number * 10 + mapping[letter]
85
86 # Check if equation is satisfied
87 if left_value == right_number:
88 return mapping
89 except:
90 # If evaluation fails, continue to next permutation
91 continue
92
93 # Edge Case: No solution found
94 return None
95# Handled Edge Cases: Empty or None puzzle, Invalid puzzle format, No terms on left side, No letters in puzzle, More letters than digits, Leading zero, 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.