For this apprach I went ahead and took a brute force approach. Firstly I went ahead an took the input
and extracted all the unique letters from it. Once that information is attained I need to get all possible
permutations of the 0-9 number combinations. This way we can check the permutations to find which of them fit
for the input given. This is done like so:
from itertools import permutations
inp = input("Input at least 3 words all separated by once space: ")
inp = inp.split(" ")
letters = CreateUniqueLettersList(inp) # create the unique letters from the input given
# create all possible permutations from the unique letters
possible = list(permutations([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], len(letters)))
The acutal permutations come in to play with the itertools function "permutation()". This function allows us
to give it a list of options, in this case our possible 0-9 digits, and then a number n. What this does is give us
all the possible ways we can have a combination of length n of the list given. A smaller example of this might look
like this:
from itertools import permutations
# create all possible permutations
possible = list(permutations([0, 1, 2], 2))
# possible = [[0, 1], [1, 2], [0, 2]]
Once we have all the possible permutations for the numbers the rest is pretty strait forward. We check each and
every one to see if that permutation is a valid option for the Cryptarithm given. This is done using the function
described
def IsValuePermutation(perm_nums, words, letters, LeadingZeros):
'''
Check to see if permutation is a valid one given the words and unique letters
:param perm_nums: permutation being checked i.e. a list of numbers
:param words: a list of our words that was given to us
:param letters: the unique letters for the given words
:param LeadingZeros: tells us if we are allowing leading zeros or not
:return: True if possible, False otherwise
'''
lookup = CreateLookUp(letters, perm_nums) # create our lookup table to be passed
WordsAsNums = []
for word in words:
num = WordToNum(word, lookup)
if LeadingZeros != "Yes":
if len(str(num)) < len(word): # this means we had a leading zero so we return false
return (False, [])
WordsAsNums.append(num)
result = 0
for i in range(len(WordsAsNums)-1): # add up our results except for the last
result += WordsAsNums[i]
if result == WordsAsNums[-1]: # if our addition matches then return true
return (True, WordsAsNums)
return (False, [])
To break this down a bit I will describe it chunk by chunk. Firstly what we will do is create our own
little look up table to make things easier. What this does is create a dictionary from our unique letters and
the current permutation of numbers being checked so that we may easily look up a number associated with a letter.
After this what we want to do is convert all the words from the input into numbers using that lookup table. This
can be done very easiy using some fancy python syntax like so:
def WordToNum(word, lookup):
return int("".join(str(lookup[letter]) for letter in word))
Then once we have all the words into their numbers for the permutation we simply check to additions of the
numbers to see if they match and if so then we can say for certain that the permutation is one that words.