let it go

Finished
1from itertools import permutations
2import re
3
14def solve(puzzle: str) -> dict[str, int] | None:
2 pass
5 """
6 Solve an alphametics puzzle.
7
8 Args:
9 puzzle: A string representing the alphametics puzzle (e.g., "SEND + MORE == MONEY")
10
11 Returns:
12 A dictionary mapping letters to digits that solves the puzzle, or None if no solution exists.
13
14 The function handles the following edge cases:
15 - Invalid puzzle format (no '==')
16 - Words with leading zeros
17 - No valid solutions
18 - Multiple operators (+, *)
19 """
20 # Edge Case: Invalid puzzle format (no '==')
21 if "==" not in puzzle:
22 return None
23
24 # Split the puzzle into left and right sides
25 left_side, right_side = puzzle.split("==")
26
27 # Parse the left side to extract terms and operators
28 # Remove spaces and split by operators
29 left_clean = left_side.replace(" ", "")
30
31 # Find all terms and operators
32 terms = re.findall(r'[A-Z]+', left_clean)
33 operators = re.findall(r'[+*]', left_clean)
34
35 # If no operators found, assume it's a single term
36 if not operators:
37 operators = ['+']
38
39 # Get all unique letters in the puzzle
40 all_words = terms + [right_side.strip()]
41 letters = set("".join(all_words))
42
43 # Edge Case: Too many unique letters (more than 10)
44 if len(letters) > 10:
45 return None
46
47 # Get the first letter of each word (cannot be zero)
48 first_letters = {word[0] for word in all_words if len(word) > 1}
49
50 # Try all possible digit assignments
51 for perm in permutations(range(10), len(letters)):
52 mapping = dict(zip(letters, perm))
53
54 # Edge Case: Leading zero in any multi-digit word
55 if any(mapping[first_letter] == 0 for first_letter in first_letters):
56 continue
57
58 # Convert words to numbers using the current mapping
59 term_values = []
60 for term in terms:
61 value = 0
62 for char in term:
63 value = value * 10 + mapping[char]
64 term_values.append(value)
65
66 # Calculate the result based on operators
67 if len(term_values) == 1:
68 total = term_values[0]
69 else:
70 total = term_values[0]
71 for i, op in enumerate(operators):
72 if op == '+':
73 total += term_values[i + 1]
74 elif op == '*':
75 total *= term_values[i + 1]
76
77 # Convert the result word to a number
78 result_value = 0
79 for char in right_side.strip():
80 result_value = result_value * 10 + mapping[char]
81
82 # Check if the equation is satisfied
83 if total == result_value:
84 return mapping
85
86 # Edge Case: No valid solution found
87 return None
88# Handled Edge Cases: Invalid puzzle format (no '=='), Too many unique letters (more than 10), Leading zero in any word, No valid solution found, Multiple operators (+, *)
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.