Find the next 1-sparse binary number

27

2

A positive integer N is K-sparse if there are at least K 0s between any two consecutive 1s in its binary representation.

So, the number 1010101 is 1-sparse whereas 101101 is not.

Your task is to find the next 1-sparse number for the given input number. For example, if the input is 12 (0b1100) output should be 16 (0b10000) and if the input is 18 (0b10010) output should be 20 (0b10100).

Smallest program or function (in bytes) wins! Standard loopholes disallowed.

articuno

Posted 2015-04-02T07:56:15.340

Reputation: 371

“next” as in “next highest” or as in “with least absolute difference” ? – FUZxxl – 2015-04-02T12:17:29.773

"next" as in "next highest". – articuno – 2015-04-02T12:21:43.890

What range of input needs to be handled? – mbomb007 – 2015-04-02T19:38:45.627

I'm going to assume negative numbers don't need to be. – mbomb007 – 2015-04-02T19:53:50.373

@articuno Can we create a function, or does it have to be a full program? Functions are pretty standard. – mbomb007 – 2015-04-03T02:35:41.833

@mbomb007 you can use standard functions – articuno – 2015-04-03T02:46:30.127

Answers

13

Pyth, 9 bytes

My first attempt at Pyth:

f!.&TyThQ

Try it here

               implicit: Q = input()            
f      hQ      find the first integer T >= Q + 1, 
               that satisfies the condition:
 !.&TyT        T & (T * 2) is 0

Digital Trauma

Posted 2015-04-02T07:56:15.340

Reputation: 64 644

9

CJam, 14 11 bytes

3 bytes saved thanks to DigitalTrauma.

l~{)___+&}g

Test it here.

Explanation

l~          "Read and eval input.";
  {      }g "Do while...";
   )_       "Increment and duplicate (call this x).";
     __+    "Get two more copies and add them to get x and 2x on the stack.";
        &   "Take their bitwise AND. This is non-zero is as long as x's base-2
             representation contains '11'.";

This leaves the last number on the stack which is printed automatically at the end of the program.

Martin Ender

Posted 2015-04-02T07:56:15.340

Reputation: 184 808

8

Python 2, 44 bytes

This is a complete python program that reads in n, and prints the answer. I think it does quite well in the readability sub-competition.

n=input()+1
while'11'in bin(n):n+=1
print n

The test results:

$ echo 12 | python soln.py 
16
$ echo 18 | python soln.py 
20

Logic Knight

Posted 2015-04-02T07:56:15.340

Reputation: 6 622

6

Pyth, 12 11 bytes

f!}`11.BThQ

Try it online: Pyth Compiler/Executor.

               implicit: Q = input()            
f        hQ    find the first integer T >= Q + 1, 
               that satisfies the condition:
 !}`11.BT         "11" is not in the binary representation of T

Jakube

Posted 2015-04-02T07:56:15.340

Reputation: 21 462

1You can save a character by turning "11" into \11`. – orlp – 2015-04-02T09:31:11.880

@orlp Thanks, should have noticed this. – Jakube – 2015-04-02T10:19:22.350

5

Mathematica, 41 30 bytes

Saved 11 bytes thanks to Martin Büttner.

#+1//.i_/;BitAnd[i,2i]>0:>i+1&

alephalpha

Posted 2015-04-02T07:56:15.340

Reputation: 23 988

3Could you add a description, please? – mbomb007 – 2015-04-02T19:09:33.797

4

Perl, 31

#!perl -p
sprintf("%b",++$_)=~/11/&&redo

Or from the command line:

 perl -pe'sprintf("%b",++$_)=~/11/&&redo' <<<"18"

nutki

Posted 2015-04-02T07:56:15.340

Reputation: 3 634

4

J, 20 characters

A monadic verb. Fixed to obey the rules.

(+1 1+./@E.#:)^:_@>:

Explanation

First, this is the verb with spaces and then a little bit less golfed:

(+ 1 1 +./@E. #:)^:_@>:
[: (] + [: +./ 1 1 E. #:)^:_ >:

Read:

    ]                             The argument
      +                           plus
        [: +./                    the or-reduction of
               1 1 E.             the 1 1 interval membership in
                      #:          the base-2 representation of the argument,
[: (                    )^:_      that to the power limit of
                             >:   the incremented argument

The argument plus the or-reduction of the 1 1 interval membership in the base-2 representation of the argument, that to the power limit applied to the incremented argument.

I basically compute if 1 1 occurs in the base-2 representation of the input. If it does, I increment the input. This is put under a power-limit, which means that it is applied until the result doesn't change any more.

FUZxxl

Posted 2015-04-02T07:56:15.340

Reputation: 9 656

Nice algorithm! It has the same length in APL: {⍵+∨/2∧/⍵⊤⍨⍵⍴2}⍣=. – Zgarb – 2015-04-02T13:52:28.930

@randomra Ah, I see. – FUZxxl – 2015-04-02T18:54:19.890

4

APL, 18 bytes

1∘+⍣{~∨/2∧/⍺⊤⍨⍺⍴2}

This evaluates to a monadic function. Try it here. Usage:

   1∘+⍣{~∨/2∧/⍺⊤⍨⍺⍴2} 12
16

Explanation

1∘+                    ⍝ Increment the input ⍺
   ⍣{            }     ⍝ until
     ~∨/               ⍝ none of
        2∧/            ⍝ the adjacent coordinates contain 1 1 in
           ⍺⊤⍨⍺⍴2      ⍝ the length-⍺ binary representation of ⍺.

Zgarb

Posted 2015-04-02T07:56:15.340

Reputation: 39 083

4

Javascript, 25 19

Using the fact that, for a 1-sparse binary number, x&2*x == 0:

f=x=>x++&2*x?f(x):x

Nick

Posted 2015-04-02T07:56:15.340

Reputation: 141

3

Python 2, 37 bytes

f=input()+1
while f&2*f:f+=1
print f

Used the logic x & 2*x == 0 for 1-sparse number.
Thanks to @Nick and @CarpetPython.

ShinMigami13

Posted 2015-04-02T07:56:15.340

Reputation: 449

Why the downvote? This works perfectly fine, and is well-golfed as well. – ETHproductions – 2017-03-31T19:15:14.293

Welcome to PPCG, btw, and nice first answer! I encourage you to continue answering challenges on the site :-) – ETHproductions – 2017-03-31T19:18:14.843

3

JavaScript (ES6), 39 43

No regexp, no strings, recursive:

R=(n,x=3)=>x%4>2?R(++n,n):x?R(n,x>>1):n

Iterative version:

F=n=>{for(x=3;x%4>2?x=++n:x>>=1;);return n}

It's very simple, just using right shift to find a sequence of 11. When I find it, skip to next number. The recursive version is directly derived from the iterative one.

Ungolfed and more obvious. To golf, the trickiest part is merging the inner and outer loops (having to init x to 3 at start)

F = n=>{
  do {
    ++n; // next number
    for(x = n; x != 0; x >>= 1) {
      // loop to find 11 in any position
      if ((x & 3) == 3) { // least 2 bits == 11
        break;
      }
    }
  } while (x != 0) // if 11 was found,early exit from inner loop and x != 0
  return n
}

edc65

Posted 2015-04-02T07:56:15.340

Reputation: 31 086

This %4>2 looks like some sorcery from Number Theory, can you please explain || provide a link? – Jacob – 2015-04-02T13:29:46.800

@Jacob (x%4>2) is simply ((x&3)==3), but with the operator precedence is JS you avoid the 2 brackets – edc65 – 2015-04-02T14:28:06.287

Simple than I thought. Now with the ungolfed version it's clear. Thanks! – Jacob – 2015-04-02T16:22:33.817

2

JavaScript, 75 66 62 bytes

Thanks to Martin Büttner for saving 9 bytes and Pietu1998 for 4 bytes!

function n(a){for(a++;/11/.test(a.toString(2));a++);return a;}

How it works: it runs a for loop starting from a + 1 as long as the current number is not 1-sparse, and if it is, the loop is interrupted and it returns the current number. To check whether a number is 1-sparse, it converts it to binary and checks whether it does not contain 11.

Un-golfed code:

function nextOneSparseNumber(num) {
    for (num++; /11/.test(num.toString(2)); num++);
    return num;
}

ProgramFOX

Posted 2015-04-02T07:56:15.340

Reputation: 8 017

2

Julia, 40 bytes

n->(while contains(bin(n+=1),"11")end;n)

This creates an anonymous function that accepts a single integer as input and returns the next highest 1-sparse integer. To call it, give it a name, e.g. f=n->..., and do f(12).

Ungolfed + explanation:

function f(n)

    # While the string representation of n+1 in binary contains "11",
    # increment n. Once it doesn't, we've got the answer!

    while contains(bin(n += 1), "11")
    end

    return(n)
end

Examples:

julia> f(12)
16

julia> f(16)
20

Suggestions and/or questions are welcome as always!

Alex A.

Posted 2015-04-02T07:56:15.340

Reputation: 23 761

2

><> (Fish), 31 + 3 = 34 bytes

1+:>:  4%:3(?v~~
;n~^?-1:,2-%2<

Usage:

>python fish.py onesparse.fish -v 12
16

3 bytes added for the -v flag.

randomra

Posted 2015-04-02T07:56:15.340

Reputation: 19 909

1

Java, 33 bytes.

Uses the method in this answer

n->{for(;(n++&2*n)>0;);return n;}

TIO

Benjamin Urquhart

Posted 2015-04-02T07:56:15.340

Reputation: 1 262

1

JavaScript (ECMAScript 6), 40

By recursion:

g=x=>/11/.test((++x).toString(2))?g(x):x

JavaScript, 56

Same without arrow functions.

function f(x){return/11/.test((++x).toString(2))?f(x):x}

nutki

Posted 2015-04-02T07:56:15.340

Reputation: 3 634

1

Scala, 65 bytes

(n:Int)=>{var m=n+1;while(m.toBinaryString.contains("11"))m+=1;m}

(if a named function is required, solution will be 69 bytes)

Jacob

Posted 2015-04-02T07:56:15.340

Reputation: 1 582

1

Python, 39 33 bytes

Try it here: http://repl.it/gpu/2

In lambda form (thanks to xnor for golfing):

f=lambda x:1+x&x/2and f(x+1)or-~x

Standard function syntax turned out to be shorter than a lambda for once!

def f(x):x+=1;return x*(x&x*2<1)or f(x)

mbomb007

Posted 2015-04-02T07:56:15.340

Reputation: 21 944

You can shorten the lambda one to 33 bytes: f=lambda x:1+x&x/2and f(x+1)or-~x. It turns out that of you bit-shift right rather than left, you can use x/2 instead of (x+1)/2 because the difference is always in zero bits of x+1. The spec asks for a program though. – xnor – 2015-04-03T00:37:00.147

I asked and he said we can do functions. Most of the answers are already. – mbomb007 – 2015-04-03T02:51:25.907

0

Perl, 16 bytes

Combining the x&2*x from various answers (I think Nick's first) with nutki's redo yields:

perl -pe'++$_&2*$_&&redo'

Tested in Strawberry 5.26.

msh210

Posted 2015-04-02T07:56:15.340

Reputation: 3 094

0

Japt, 8 bytes

_&ZÑ}fUÄ

Run it online.

Oliver

Posted 2015-04-02T07:56:15.340

Reputation: 7 160

0

Jelly, 7 bytes

‘&Ḥ¬Ɗ1#

A full program accepting a single, non-negative integer which prints a positive integer (as a monadic link it yields a list containing a single positive integer).

Try it online!

How?

Starting at v=n+1, and incrementing, double v to shift every bit up one place and bit-wise AND with v and then perform logical NOT to test if v is 1-sparse until one such number is found.

‘&Ḥ¬Ɗ1# - Main Link: n   e.g. 12
‘       - increment           13
     1# - 1-find (start with that as v and increment until 1 match is found) using:
    Ɗ   -   last three links as a dyad:
  Ḥ     -   double v
 &      -   (v) bit-wise AND (with that)
   ¬    -   logical NOT (0->1 else 1)
        - implicit print (a single item list prints as just the item would)

Jonathan Allan

Posted 2015-04-02T07:56:15.340

Reputation: 67 804

0

Stax, 5 bytes

╦>ù╤x

Run and debug it

It works using this procedure. The input starts on top of the stack.

  • Increment and copy twice.
  • Halve the top of the stack.
  • Bitwise-and top two elements on the stack.
  • If the result is truthy (non-zero) repeat the entire program.

recursive

Posted 2015-04-02T07:56:15.340

Reputation: 8 616

0

Ruby, 44

->(i){loop{i+=1;break if i.to_s(2)!~/11/};i}

Pretty basic. A lambda with an infinite loop and a regexp to test the binary representation. I wish that loop yielded and index number.

Max

Posted 2015-04-02T07:56:15.340

Reputation: 101

@mbomb007 done. thanks for the tip. – Max – 2015-04-02T19:52:33.067

0

Matlab (77 74 bytes)

m=input('');for N=m+1:2*m
if ~any(regexp(dec2bin(N),'11'))
break
end
end
N

Notes:

  • It suffices to test numbers m+1 to 2*m, where m is the input.
  • ~any(x) is true if x contains all zeros or if x is empty

Luis Mendo

Posted 2015-04-02T07:56:15.340

Reputation: 87 464

0

C (32 bytes)

f(int x){return 2*++x&x?f(x):x;}

Recursive implementation of the same algorithm as so many other answers.

Alchymist

Posted 2015-04-02T07:56:15.340

Reputation: 544