DAILY CODING PROBLEM: #81
Ryan N Wilson | 2021-01-12
Problem:
Given a mapping of digits to letters (as in a phone number), and a digit string, return all possible letters the number could represent. You can assume each valid number in the mapping is a single digit. For example if:
{"2": ["a", "b", "c"], "3": ["d", "e", "f"], …}
then “23” should return
["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
Code a solution”
SOLUTION:
import math # I'll use this to round down later
# Primary Function
# Given a string of numbers, and a mapping of
# individual numbers to an assortment of letters,
# return an array of letter compinations that
# correspond to the given numbers.
def displayConfigurations(number, mapping):
#initialize variables
preList = []
finalList = []
string = ""
totalLength = 1
# Create an array where each item in the array
# corresponds to a number in the given string of numbers.
# Each item will be a subarray of all letter that are
# mapped to the number.
for i in number:
preList.append(findLetters(i, mapping))
# The total number of possible combinations is the product
# of the lengths of all the subarrays.
for i in range(0, len(preList)):
totalLength *= len(preList[i])
# Create an array called finalList. If the first number has 3
# letters mapped to it, then the fist third of the combinations
# will begin with the first letter, the second third with the
# second letter, and the final third with the third letter. Each
# third will be referred to as an interval. I'll build out the
# finalList array by doing this first pass here:
interval = totalLength / len(preList[0])
for i in range(0, totalLength):
j = math.floor(i / interval)
finalList.append(preList[0][j])
# Following this each interval can be broken down into smaller
# intervals by dividing by the size of the number of combinations
# of the next letter. We can keep subdividing our interval until
# we get through all of the numbers in the string of number provided.
# We keep appending letters at each step untill we've worked through
# every combination
for i in range(1, len(preList)):
interval = interval / len(preList[i])
for k in range(0, totalLength):
j = math.floor(k / interval)
while j >= len(preList[i]):
j = j - len(preList[i])
finalList[k] += preList[i][j]
# Print the final result
print(finalList)
# HELPER FUNTIONS-------------------------------------------
# Create class to assign an array of letters to each number
class numberMapping:
def __init__(self, num, letters):
self.num = num
self.letters = letters
# Given a number and a mapping, return the letters mapped to that number
def findLetters(num, mapping):
for i in range(0, len(mapping)):
if mapping[i].num == num:
return mapping[i].letters
def main():
#Create the specific mapping defined in the problem
mapping = []
mapping.append(numberMapping("2", ["a", "b", "c"]))
mapping.append(numberMapping("3", ["d", "e", "f"]))
mapping.append(numberMapping("4", ["g", "h", "i"]))
mapping.append(numberMapping("5", ["j", "k", "l"]))
mapping.append(numberMapping("6", ["m", "n", "o"]))
mapping.append(numberMapping("7", ["p", "q", "r", "s"]))
mapping.append(numberMapping("8", ["t", "u", "v"]))
mapping.append(numberMapping("9", ["w", "x", "y", "z"]))
#Run the example in the problem
print("Letter combinations for '23'")
num = "23"
displayConfigurations(num, mapping)
#Run a more complex example
print("Letter combinations for '987'")
num = "987"
displayConfigurations(num, mapping)
if __name__ == "__main__":
main()
Here’s the results when I run the python script:
Letter combinations for ‘23’
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']
Letter combinations for ‘987’
['wtp', 'wtq', 'wtr', 'wts', 'wup', 'wuq', 'wur', 'wus',
'wvp', 'wvq', 'wvr', 'wvs', 'xtp', 'xtq', 'xtr', 'xts',
'xup', 'xuq', 'xur', 'xus', 'xvp', 'xvq', 'xvr', 'xvs',
'ytp', 'ytq', 'ytr', 'yts', 'yup', 'yuq', 'yur', 'yus',
'yvp', 'yvq', 'yvr', 'yvs', 'ztp', 'ztq', 'ztr', 'zts',
'zup', 'zuq', 'zur', 'zus', 'zvp', 'zvq', 'zvr', 'zvs']