Generate 10-digit number using a phone keypad

srikanta picture srikanta · May 23, 2010 · Viewed 13.8k times · Source

Given a phone keypad as shown below:

1 2 3
4 5 6
7 8 9
  0

How many different 10-digit numbers can be formed starting from 1? The constraint is that the movement from 1 digit to the next is similar to the movement of the Knight in a chess game.

For eg. if we are at 1 then the next digit can be either 6 or 8 if we are at 6 then the next digit can be 1, 7 or 0.

Repetition of digits are allowed - 1616161616 is a valid number.

Is there a polynomial time algorithm which solves this problem? The problem requires us to just give the count of 10-digit numbers and not necessarily list the numbers.

EDIT: I tried modeling this as a graph with each digit having 2 or 3 digits as its neighbors. Then I used DFS to navigate upto the depth of 10 nodes and then increment the count of numbers each time I reached the depth of 10. This obviously is not polynomial time. Assuming each digit had just 2 neighbors, this would have required at least 2^10 iterations.

The variable here is the number of digits. I have taken the eg. of 10 digit numbers. It could as well be n-digits.

Answer

aioobe picture aioobe · May 23, 2010

Sure it can be done in polynomial time. It's an excellent exercise in dynamic programming or memoization.

Lets assume N (the number of digits) equals 10 for the example.

Think of it recursively like this: How many numbers can I construct using 10 digits starting from 1?

Answer is

[number of 9-digit numbers starting from 8] +
[number of 9-digit numbers starting from 6].

So how many "9-digit numbers starting from 8" are there? Well,

[number of 8-digit numbers starting from 1] +
[number of 8-digit numbers starting from 3]

and so on. Base case is reached when you get the question "How many 1-digit numbers are there starting from X" (and the answer is obviously 1).

When it comes to complexity, the key observation is that you reuse previously computed solutions. That is for instance, the answer to "how many 5-digit numbers starting from 3" there are, can be used both when answering "how many 6-digit numbers are there starting from 8" AND "how many 6-digit numbers are there starting from 4". This reuse make the complexity collapse from exponential to polynomial.

Let's take a closer look at the complexity of a dynamic programming solution:

Such implementation would fill in a matrix in the following way:

num[1][i] = 1, for all 0<=i<=9   -- there are one 1-digit number starting from X.

for digits = 2...N
    for from = 0...9
        num[digits][from] = num[digits-1][successor 1 of from] +
                            num[digits-1][successor 2 of from] +
                            ...
                            num[digits-1][successor K of from]

return num[N][1]                 -- number of N-digit numbers starting from 1.

The algorithm simply fills the matrix one cell at a time, and the matrix is of dimension 10*N, and thus runs in linear time.


Wrote it down from the top of my head, please correct me if there are any typos.