Given an integer N. What is the smallest integer greater than N that only has 0 or 1 as its digits?

  1. Increment N,

  2. Starting from the left, scan until you find a digit above 1. Increment the partial number before it and zero out the rest.

E.g.

12 -> 13 -> 1|3 -> 10|0
101 -> 102 -> 10|2 -> 11|0
109 -> 110 -> 110|
111 -> 112 -> 11|2 -> 100|0
198 -> 199 -> 1|99 -> 10|00
1098 -> 1099 -> 10|99 -> 11|00
10203 -> 10204 -> 10|204 -> 11|000
111234 -> 111235 -> 111|235 -> 1000|000
...

Proof:

The requested number must be at least N+1, this is why we increment. We are now looking for a number greater or equal.

Let us call the prefix the initial 0/1 digits and suffix what comes after. We must replace the first digit of the suffix by a zero and set a larger prefix. The smallest prefix that fits is the current prefix plus one. And the smallest suffix that fits is all zeroes.


Update:

I forgot to specify that the prefix must be incremented as a binary number, otherwise forbidden digits could appear.


Another possibility would be the following one:

  • You start with the largest decimal number of the type "1111111...1111" supported by the data type used

    The algorithm assumes that the input is smaller than this number; otherwise you'll have to use another data type.

    Example: When using long long, you start with the number 1111111111111111111.

  • Then process each decimal digit from the left to the right:
    • Try to change the digit from 1 to 0.
    • If the result is still larger than your input, do the change (change the digit to 0).
    • Otherwise the digit remains 1.

Example

Input = 10103
Start:  111111
Step 1: [1]11111, try [0]11111; 011111 > 10103 => 011111 
Step 2: 0[1]1111, try 0[0]1111; 001111 < 10103 => 011111
Step 3: 01[1]111, try 01[0]111; 010111 > 10103 => 010111
Step 4: 010[1]11, try 010[0]11; 010011 < 10103 => 010111
Step 5: 0101[1]1, try 0101[0]1; 010101 < 10103 => 010111
Step 6: 01011[1], try 01011[0]; 010110 > 10103 => 010110
Result: 010110

Proof of correctness:

We process digit by digit in this algorithm. In each step, there are digits whose value is already known and digits whose values are not known, yet.

In each step, we probe the leftmost unknown digit.

We set that digit to "0" and all other unknown digits to "1". Because the digit to be probed is the most significant of the unknown digits, the resulting number is the largest possible number with that digit being a "0". If this number is less or equal the input, the digit being probed must be a "1".

On the other hand, the resulting number is smaller than all possible numbers where the digit being probed is a "1". If the resulting number is larger than the input, the digit must be "0".

This means that we can calculate one digit in each step.

C code

(The C code should work under C++, too):

long long input;
long long result;
long long digit;

... read in input ...

result = 1111111111111111111ll;
digit = 1000000000000000000ll;

while( digit > 0 )
{
    if(result - digit > input)
    {
        result -= digit;
    }
    digit /= 10;
}

... print out output ...

Let me suggest a couple of alternatives.

I. Incrementing. Consider it a modification of @YvesDaoust method.

  1. Increase N by 1
  2. Expand result with leading zero
  3. Go from the last to the second digit
    (a) if it is less than 2 then leave everything as is
    (b) otherwise set it to 0 and increase preceding
  4. Repeat steps 3a,b

Examples:

1. N = 0 -> 1 -> (0)|(1) -> 1
2. N = 1 -> 2 -> (0)|(2) -> (1)|(0) -> 10
3. N = 101 -> 102 -> (0)|(1)(0)(2) -> (0)|(1)(1)(0) -> (0)|(1)(1)(0) -> (0)|(1)(1)(0) -> 110
4. N = 298 -> 299 -> (0)|(2)(9)(9) -> (0)|(2)(10)(0) -> (0)|(3)(0)(0) -> (1)|(0)(0)(0) -> 1000

You get result in decimal format.


II. Dividing.

  1. Increase N by 1
  2. Set sum to 0
  3. Divide result by 10 to get div (D) and mod (M) parts
  4. Check M
    (a) if M exceeds 1 then increase D
    (b) otherwise increase sum by M*10k, where k is the current iteration number (starting with 0)
  5. Repeat steps 3,4 until D is 0

Example 1:

1. N = 0 -> N = 1
2. sum = 0
3. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^0 == 1
4. D == 0 -> sum == 1

Example 2:

1. N = 1 -> N = 2
2. sum = 0
3. 2/10 -> D == 0, M == 2 -> D = D + 1 == 1
4. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^1 == 10
5. D == 0, sum == 10

Example 3:

1. N = 101 -> N = 102
2. sum = 0
3. 102/10 -> D == 10, M == 2 -> D = D + 1 == 11
4. 11/10 -> D == 1, M == 1 -> sum = sum + 1*10^1 = 10
5. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^2 == 10 + 100 == 110
6. D == 0, sum == 110

Example 4:

1. N = 298 -> N = 299
2. sum = 0
3. 299/10 -> D == 29, M == 9 -> D = D + 1 == 30
4. 30/10 -> D == 3, M == 0 -> sum = sum + 0*10^1 == 0
5. 3/10 -> D == 0, M == 3 -> D = D + 1
6. 1/10 -> D == 0, M == 1 -> sum = sum + 1*10^3 == 1000
7. D == 0, sum == 1000

Tags:

Algorithm

C++