let it go

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 handles puzzles with addition, subtraction, and multiplication operations
12 where letters represent unique digits. Leading digits cannot be zero.
13 """
14 # Edge Case: Empty or None puzzle
15 if not puzzle:
16 return None
17
18 # Parse the puzzle
19 puzzle = puzzle.replace("==", "=").replace(" ", "")
20
21 # Determine the operator and split the puzzle
22 if "=" not in puzzle:
23 return None
24
25 # Find the operator
26 operator = None
27 operators = ['*', '-', '+']
28 left_side = None
29 right_side = None
30
31 # Check for each operator in order of precedence
32 for op in operators:
33 if op in puzzle and puzzle.count("=") == 1:
34 parts = puzzle.split("=")
35 if len(parts) == 2 and op in parts[0]:
36 left_side, right_side = parts[0], parts[1]
37 operator = op
38 break
39
40 # Edge Case: Invalid puzzle format
41 if operator is None or left_side is None or right_side is None:
42 return None
43
44 # Split the left side based on the operator
45 operands = left_side.split(operator)
46
47 # Edge Case: Invalid number of operands
48 if len(operands) < 2 or any(not operand for operand in operands):
49 return None
50
51 # Edge Case: Empty right side
52 if not right_side:
53 return None
54
55 # Extract all unique letters
56 letters = set()
57 for part in operands + [right_side]:
58 letters.update(part)
59
60 # Edge Case: No letters in puzzle
61 if not letters:
62 return None
63
64 # Extract first letters (can't be zero)
65 first_letters = {word[0] for word in operands + [right_side]}
66
67 # Edge Case: More than 10 unique letters (impossible to assign unique digits)
68 if len(letters) > 10:
69 return None
70
71 # Convert letters to a list for indexing
72 letters_list = list(letters)
73
74 # Try all permutations of digits for the letters
75 from itertools import permutations
76
77 # Edge Case: Handle puzzles with no solution by returning None
78 for perm in permutations(range(10), len(letters)):
79 mapping = dict(zip(letters_list, perm))
80
81 # Check if any first letter is assigned zero
82 if any(mapping[letter] == 0 for letter in first_letters):
83 continue
84
85 # Calculate the value of the first operand
86 first_value = 0
87 for char in operands[0]:
88 first_value = first_value * 10 + mapping[char]
89
90 # Apply the operator with remaining operands
91 result_value = first_value
92
93 if operator == "+":
94 for i in range(1, len(operands)):
95 operand_value = 0
96 for char in operands[i]:
97 operand_value = operand_value * 10 + mapping[char]
98 result_value += operand_value
99 elif operator == "-":
100 for i in range(1, len(operands)):
101 operand_value = 0
102 for char in operands[i]:
103 operand_value = operand_value * 10 + mapping[char]
104 result_value -= operand_value
105 elif operator == "*":
106 for i in range(1, len(operands)):
107 operand_value = 0
108 for char in operands[i]:
109 operand_value = operand_value * 10 + mapping[char]
110 result_value *= operand_value
111
112 # Calculate the value of the result
113 expected_result = 0
114 for char in right_side:
115 expected_result = expected_result * 10 + mapping[char]
116
117 # Check if the equation is satisfied
118 if result_value == expected_result:
119 return mapping
120
121 # No solution found
122 return None
123
124# Handled Edge Cases: Empty or None puzzle, Invalid puzzle format, No addends on left side, Empty right side, No letters in puzzle, More than 10 unique letters, Puzzles with no solution
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.