Working through a few problems on LeetCode. I haven’t quite decided what I think of the site, but it’s a fun way to play with simple algorithms. Figured I might as well write up any I find interesting.
First interesting problem:
Given a standard lettered keypad, generate all words from a given phone number.
def letterCombinations(self, digits: str) -> List[str]:
if not digits:
return []
letters = {
'1': '',
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz',
'0': ' ',
}
return [
''.join(product)
for product in itertools.product(*[
letters[digit] for digit in digits
])
]
I’m going to be perhaps a little overzealous when it comes to coding that. From the inside out:
- Loop over the digits with
for digit in digits
- Get the letters for each of those with
letters[digit]
- Generate all combinations of letters with
itertools.product
(strings are iterable) - Join then all back together with
''.join(product)
And that’s all we need. I do love list comprehension in Python. Makes me think I’m writing in a proper language like Lisp/Scheme/Racket. :D (I should write more Racket, it’s been a while).
A few tests to make sure I’m doing something sensible:
class TestSolution(unittest.TestCase):
def test_1(self):
self.assertEqual(
letterCombinations("23"),
["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
)
def test_2(self):
self.assertEqual(
letterCombinations(""),
[]
)
def test_3(self):
self.assertEqual(
letterCombinations("2"),
["a", "b", "c"]
)
if __name__ == '__main__':
unittest.main()
And there we go:
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK