Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating all the increasing digit numbers

Tags:

java

c#

I came across the following question for an interview.

For a given number of digits, generate all the numbers such that the value of a higher order digit is less than a lower order digit.

145 // 1 < 4 < 5

Is there a better (efficient) way to do this than the one I have come up with:

public static void GenerateSpecialNumbers(int noDigits)
{           
    int prod = 1;
    for(int i=0; i < noDigits; i++)
    {
        prod = prod * 10;
    }
    int minValue = prod/10;
    int maxValue = prod - 1;        

    for(int i = minValue; i < maxValue; i++)
    {
        bool isValid = true;

        int num  = i;
        int max = int.MaxValue;

        while(num > 0)
        {
            int digit = num % 10;
            if(digit >= max)
            {
                isValid = false;
                break;
            }
            max = digit;            

            num = num/10;
        }

        if(isValid)
            Console.WriteLine(i);               
    }
}

EDIT: Output for 3 digits:

123 124 125 126 127 128 129 134 135 136 137 138 139 145 146 147 148 149 156 157 158 159 167 168 169 178 179 189 234 235 236 237 238 239 245 246 247 248 249 256 257 258 259 267 268 269 278 279 289 345 346 347 348 349 356 357 358 359 367 368 369 378 379 389 456 457 458 459 467 468 469 478 479 489 567 568 569 578 579 589 678 679 689 789

like image 624
blitzkriegz Avatar asked Feb 08 '12 22:02

blitzkriegz


5 Answers

Nice puzzle! Here's my take:

static void Main()
{
    WriteNumbers(3);
}

static void WriteNumbers(int digits, int number = 0)
{
    int i = (number % 10) + 1;
    number *= 10;
    for (; i <= 9; i++)
    {
        if (digits == 1)
            Console.WriteLine(number + i);
        else
            WriteNumbers(digits - 1, number + i);
    }
}
like image 157
Hand-E-Food Avatar answered Oct 28 '22 14:10

Hand-E-Food


Yes, this problem has a simple recursive description that constructs all the numbers without having to test and throw any away.

For example, the valid n digit numbers include "1".append(all valid n-1 digit numbers using only digits >1)

Each digit has a lower bound of one plus the digit immediately to its left. Can you find a simple upper bound?

like image 25
Ben Voigt Avatar answered Oct 28 '22 14:10

Ben Voigt


Since I like table-based things, I would generate the table for n = 2 first (< 100 entries, obviously) and just hold it in an initialized array.

Then f(n) = the digits in the sequence N [1, 2, 3, 4, 5, 6, 7, 8, 9] composed with f(n-1) where f(n-1)[0] > N

i.e. for n = 3:
1, f(2) where f(2)[0] > 1: 123, 124, 125, ...
2, f(2) where f(2)[0] > 2: 234, 235, 236, ...
...
like image 28
Cade Roux Avatar answered Oct 28 '22 14:10

Cade Roux


for (i1 from 1 to 9)
for (i2 from 1 to i1 - 1)
for (i3 from 1 to i2 - 1)
 print(i1 * 1 + i2 * 10 + i3 * 100);

No recursion needed for fixed-length numbers. Easy to code and fail-safe.

Please note that the loop upper bounds are not fixed. This is what makes this work.

like image 38
usr Avatar answered Oct 28 '22 13:10

usr


Here is my solution with help from @Hand-E-Food and @Ben Voigt's comment. I feel this is easier to understand:

        static void WriteNumbers(int digits, int left=0,int number=0)
        {
           for(int i=left+1; i<10; i++)
           {
               if(digits==1)
               {
                   Console.WriteLine(number*10+i);
               }
               else
               {
                   WriteNumbers(digits - 1, i, number*10 + i);
               }
           }
        }
like image 1
Bolu Avatar answered Oct 28 '22 14:10

Bolu