Given an equation, represented by words
on the left side and the result
on the right side.
You need to check if the equation is solvable under the following rules:
words[i]
and result
are decoded as one number without leading zeros.words
) will equal to the number on the right side (result
).Return true
if the equation is solvable, otherwise return false
.
Example 1:
Input: words = ["SEND","MORE"], result = "MONEY" Output: true Explanation: Map 'S'-> 9, 'E'->5, 'N'->6, 'D'->7, 'M'->1, 'O'->0, 'R'->8, 'Y'->'2' Such that: "SEND" + "MORE" = "MONEY" , 9567 + 1085 = 10652
Example 2:
Input: words = ["SIX","SEVEN","SEVEN"], result = "TWENTY" Output: true Explanation: Map 'S'-> 6, 'I'->5, 'X'->0, 'E'->8, 'V'->7, 'N'->2, 'T'->1, 'W'->'3', 'Y'->4 Such that: "SIX" + "SEVEN" + "SEVEN" = "TWENTY" , 650 + 68782 + 68782 = 138214
Example 3:
Input: words = ["LEET","CODE"], result = "POINT" Output: false Explanation: There is no possible mapping to satisfy the equation, so we return false. Note that two different characters cannot map to the same digit.
Constraints:
2 <= words.length <= 5
1 <= words[i].length, result.length <= 7
words[i], result
contain only uppercase English letters.10
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force strategy for solving verbal arithmetic puzzles involves trying every possible combination of number assignments to the letters. We check if each combination makes the equation true, and if so, we've found a solution. It's like trying every key on a keyring to see which one unlocks a door.
Here's how the algorithm would work step-by-step:
def solve_verbal_arithmetic(equation):
words = equation.replace('+', ' ').replace('=', ' ').split()
unique_characters = ''.join(sorted(set(''.join(words))))
number_of_unique_characters = len(unique_characters)
if number_of_unique_characters > 10:
return None
import itertools
for digits_permutation in itertools.permutations(range(10), number_of_unique_characters):
# Assign digits to characters
character_to_digit = dict(zip(unique_characters, digits_permutation))
# Check if leading digit is zero
if any(character_to_digit[word[0]] == 0 for word in words):
continue
# Evaluate the equation
values = [int(''.join(str(character_to_digit[character]) for character in word)) for word in words]
if len(values) >= 3:
if values[-1] == sum(values[:-1]):
return character_to_digit
return None
The most efficient way to solve this puzzle is to use constraint satisfaction and backtracking. We assign digits to letters one by one, checking if the partial solution is still valid based on the arithmetic rules. If it's not valid, we backtrack and try a different digit.
Here's how the algorithm would work step-by-step:
def solve_verbal_arithmetic(equation):
words = equation.replace('+', ' ').replace('=', ' ').split()
unique_characters = ''.join(sorted(set(''.join(words))))
first_letters = {word[0] for word in words}
def string_to_number(word, letter_to_digit):
number = 0
for char in word:
number = number * 10 + letter_to_digit[char]
return number
def is_solution_valid(letter_to_digit, words):
left_side = sum(string_to_number(word, letter_to_digit) for word in words[:-1])
right_side = string_to_number(words[-1], letter_to_digit)
return left_side == right_side
def solve(index, letter_to_digit, used_digits):
if index == len(unique_characters):
return is_solution_valid(letter_to_digit, words)
letter = unique_characters[index]
for digit in range(10):
if digit in used_digits:
continue
# Leading zeros aren't allowed
if digit == 0 and letter in first_letters:
continue
letter_to_digit[letter] = digit
used_digits.add(digit)
# Backtrack to explore other possibilities
if solve(index + 1, letter_to_digit, used_digits):
return True
# Reset for backtracking step to find solution
used_digits.remove(digit)
del letter_to_digit[letter]
return False
letter_to_digit = {}
used_digits = set()
if solve(0, letter_to_digit, used_digits):
return letter_to_digit
else:
return None
Case | How to Handle |
---|---|
Empty input strings for words or result | Return false immediately since there is no valid puzzle to solve |
Words or result contain characters other than uppercase letters | Reject the input and return false or throw an exception since only uppercase letters are valid |
The same letter appears at the beginning of multiple words or the result | Track leading characters to ensure no leading zero constraints are violated during assignment |
The length of the result is shorter than one of the input words | Return false immediately since the sum cannot be shorter than the addends |
No valid solution exists for the given puzzle | The backtracking search algorithm should exhaust all possibilities and return false if no solution is found |
Multiple valid solutions exist | The problem usually asks for only one solution; the algorithm can stop and return the first solution found |
Integer overflow during intermediate additions | Use a data type that can accommodate large numbers or check for overflow before assigning values to prevent incorrect calculations |
Words or result start with the same letter, and that letter has a value of zero | Ensure that the leading digit cannot be zero during assignment. |