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
```