blitzkriegz
blitzkriegz

Reputation: 9576

Generating all the increasing digit numbers

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

Upvotes: 5

Views: 1763

Answers (7)

Bolu
Bolu

Reputation: 8786

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);
               }
           }
        }

Upvotes: 1

usr
usr

Reputation: 171188

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.

Upvotes: 1

ggrigery
ggrigery

Reputation: 411

Here's a solution (albeit kind of hack-ish) that will work for any number of digits:

private static void printSpecialNumbers(int noOfDigits){
    int max = (int) Math.pow(10, noOfDigits);
    int min = (int) Math.pow(10, noOfDigits-1);

    for(int i = min; i < max; i++){
        if(isSpecialNumber(i))
            System.out.println(i);
    }
}

private static boolean isSpecialNumber(int i){

    String intString = String.valueOf(i);
    String[] digits = intString.split("");

    for(int k = 1; k < digits.length-1; k++){
        if(Integer.valueOf(digits[k]) >= Integer.valueOf(digits[k+1]))
            return false;
    }

    return true;
}

Upvotes: 0

supercat
supercat

Reputation: 81143

Here's a hint: if there are N possible digit values, and you want to pick M of them, the number of possibilities is "N choose M".

Upvotes: 0

Hand-E-Food
Hand-E-Food

Reputation: 12794

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);
    }
}

Upvotes: 3

Cade Roux
Cade Roux

Reputation: 89661

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, ...
...

Upvotes: 1

Ben Voigt
Ben Voigt

Reputation: 283624

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?

Upvotes: 2

Related Questions