## Words On A Telephone Keypad

### January 13, 2017

The digits on a telephone keypad are associated with letters; for instance, the digit 2 is associated with the letters A, B and C, and the digit 7 is associated with the letters P, Q, R and S. Thus, a word can be converted to its numeric equivalent; for instance, PRAXIS can be converted to the number 772947. The conversion is not necessarily unique, so ACT, BAT and CAT all convert to 228.

Your task is to write a program that takes a number, such as 228, and returns a list of all the words in a dictionary that are represented by that number. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 3 Responses to “Words On A Telephone Keypad”

1. Jamie Hope said

Here’s one that goes the other way, turning the provided number into a string regex, and then using grep to search /usr/share/dict/words (via a Kawa process quasi-literal).

```(import (srfi 13))                      ; for string-join
(require 'regex)                        ; for regex-split

(define letters
["[+]" "1" "[abc]" "[def]" "[ghi]" "[jkl]" "[mno]" "[pqrs]" "[tuv]" "[wxyz]"])

(define (digits n::integer)
(let loop ((ds '()) (n n))
(if (< n 10)
(cons n ds)
(loop (cons (remainder n 10) ds) (div n 10)))))

(define (num->regex n::integer)
(string-join (map letters (digits n)) ""))

(define (paragraph->lines s::String)
(regex-split #/\n/ (*:trim s)))

(define (lookup n::integer)
(paragraph->lines
&`{grep -i "^&[(num->regex n)]\$" /usr/share/dict/words}))

(for-each
(lambda (arg)
(format #t "~a: ~a~%" arg (lookup (string->number arg))))
(cdr (command-line)))
```

\$ kawa /tmp/words.scm 772947 228
772947: (praxis)
228: (Abu abu act Bat bat Cat cat)

2. matthew said

@Jamie: Great idea! Here’s a node.js version:

```const readline = require('readline');
const s = process.argv || "43556";
const map = ['[+]','1','[abc]','[def]','[ghi]','[jkl]','[mno]','[pqrs]','[tuv]','[wxyz]'];
let restr = "";
for (const c of s.split('')) {
restr += map[Number(c)] || "";
}
restr = "^" + restr + "\$"; // Match whole line

const re = new RegExp(restr,"i"); // Case insensitive

input: process.stdin;
});

rl.on('line', function(line){
if (re.test(line)) console.log(line);
})
```
```\$ cat /usr/share/dict/words | nodejs --harmony phone.js
hello
\$ cat /usr/share/dict/words | nodejs --harmony phone.js 666
Mon
Ono
mom
moo
non
```
3. r. clayton said

A solution in bash.