Finished
1import itertools
2import re
3
14def solve(puzzle: str) -> dict[str, int] | None:
2 pass
5 # Parse the puzzle into words
6 # Edge Case: Invalid puzzle format
7 if '==' not in puzzle:
8 # Try to handle single equation (no ==)
9 parts = puzzle.replace('=', '==').split('==')
10 if len(parts) != 2:
11 return None
12 left_side, right_side = parts[0].strip(), parts[1].strip()
13 else:
14 parts = puzzle.split('==')
15 if len(parts) != 2:
16 return None
17 left_side, right_side = parts[0].strip(), parts[1].strip()
18
19 # Extract all words (sequences of letters)
20 words = re.findall(r'[A-Z]+', puzzle)
21
22 # Edge Case: No words found
23 if not words:
24 return None
25
26 # Get all unique letters
27 unique_letters = set(''.join(words))
28
29 # Edge Case: More than 10 unique letters (impossible to solve)
30 if len(unique_letters) > 10:
31 return None
32
33 # Get first letters of each word (can't be zero)
34 first_letters = {word[0] for word in words}
35
36 # Edge Case: Empty words
37 if any(len(word) == 0 for word in words):
38 return None
39
40 # Try all permutations of digits for the unique letters
41 digits = range(10)
42 for perm in itertools.permutations(digits, len(unique_letters)):
43 mapping = dict(zip(unique_letters, perm))
44
45 # Edge Case: Leading zero
46 if any(mapping[letter] == 0 for letter in first_letters):
47 continue
48
49 # Convert words to numbers using the current mapping
50 def word_to_number(word):
51 return int(''.join(str(mapping[letter]) for letter in word))
52
53 # Parse and evaluate the left side
54 # Split by + and - to handle addition and subtraction
55 # We need to be careful with the parsing
56
57 # Convert words to numbers and evaluate the equation
58 try:
59 # Parse the left side and right side separately
60 # Handle different operators (+, -, *)
61
62 # Process left side - handle different operators
63 # Find all words and operators in the left side
64 tokens = re.findall(r'[A-Z]+|[+*-]', left_side)
65
66 if not tokens:
67 continue
68
69 # Convert words to numbers and evaluate
70 left_value = 0
71 current_op = '+'
72 first_number = True
73
74 for token in tokens:
75 if token in ['+', '-', '*']:
76 current_op = token
77 else:
78 # Convert word to number
79 word_value = int(''.join(str(mapping[letter]) for letter in token))
80
81 if first_number:
82 left_value = word_value
83 first_number = False
84 elif current_op == '+':
85 left_value += word_value
86 elif current_op == '-':
87 left_value -= word_value
88 elif current_op == '*':
89 left_value *= word_value
90
91 # Process right side
92 right_words = re.findall(r'[A-Z]+', right_side)
93 if len(right_words) != 1:
94 continue
95 right_value = int(''.join(str(mapping[letter]) for letter in right_words[0]))
96
97 # Check if equation is satisfied
98 if left_value == right_value:
99 return mapping
100 except:
101 # If there's any error in evaluation, continue to next permutation
102 continue
103
104 # Edge Case: No solution found
105 return None
106# Handled Edge Cases: Invalid puzzle format, No words found, More than 10 unique letters, Empty words, Leading zero, Malformed expression, 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.