24
\$\begingroup\$

A bit floats from the LSB to the MSB moving one position each time until it floats to the top of the container:

0000
0001
0010
0100
1000

Once one bit floats to the top, another bit begins its journey and it stops when it meets other bit:

1001
1010
1100

This happens until the container is filled with bits:

1101
1110
1111

Challenge

Given an integer number, output the "Bit floating sequence" for a container of that number of bits.

  • Each term of the sequence can be separated by any separator of your choice.
  • Edit: Sequence must be shown as decimal integer numbers, starting by the first therm: 0.
  • The container size sould be greater than zero and up to the number of bits of the bigest integer suported by the language of your choice. You can assume that the input always match this requirement.

Examples

Only the numeric sequence is required, binary representation is shown as example:

  • For 1: 0 1

    0 -> 0
    1 -> 1
    
  • For 3: 0 1 2 4 5 6 7

    000 -> 0
    001 -> 1
    010 -> 2
    100 -> 4
    101 -> 5
    110 -> 6
    111 -> 7
    
  • For 4: 0 1 2 4 8 9 10 12 13 14 15

    0000 -> 0
    0001 -> 1
    0010 -> 2
    0100 -> 4
    1000 -> 8
    1001 -> 9
    1010 -> 10
    1100 -> 12
    1101 -> 13
    1110 -> 14
    1111 -> 15
    
  • For 8: 0 1 2 4 8 16 32 64 128 129 130 132 136 144 160 192 193 194 196 200 208 224 225 226 228 232 240 241 242 244 248 249 250 252 253 254 255

    00000000 -> 0
    00000001 -> 1
    00000010 -> 2
    00000100 -> 4
    00001000 -> 8
    ...
    ...
    ...
    11111000 -> 248
    11111001 -> 249
    11111010 -> 250
    11111100 -> 252
    11111101 -> 253
    11111110 -> 254
    11111111 -> 255
    
asked Sep 6, 2019 at 9:48
\$\endgroup\$
4
  • 2
    \$\begingroup\$ May we output the sequence in any order (i.e. reversed), or do they have to be sorted from lowest to highest? \$\endgroup\$ Commented Sep 6, 2019 at 12:00
  • 1
    \$\begingroup\$ May we output as floats? E.g. [0.0, 1.0] \$\endgroup\$ Commented Sep 6, 2019 at 13:09
  • 8
    \$\begingroup\$ May we output using the binary representation? \$\endgroup\$ Commented Sep 6, 2019 at 21:01
  • \$\begingroup\$ May we output the zero-indexed sequence? i.e. 0 -> [0, 1] \$\endgroup\$ Commented Sep 6, 2019 at 22:36

19 Answers 19

7
\$\begingroup\$

05AB1E, 10 bytes

LRL ̃Íoî.\ï

Try it online!

L # range [1..input]
 R # reversed
 L # convert each to a range: [[1..input], [1..input-1], ..., [1]]
 ̃ # flatten
 Í # subtract 2 from each
 o # 2**each
 î # round up (returns a float)
 ï # convert to integer
 .\ # undelta
answered Sep 6, 2019 at 13:08
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I think there is a meta-post somewhere allowing floats with .0 by default for integers, but not sure. I personally usually put the ï in the footer to pretty-print and don't include it in the byte-count. \$\endgroup\$ Commented Sep 6, 2019 at 13:38
7
\$\begingroup\$

Python 2, 45 bytes

y=n=2**input()
while y:print n-y;y=y&y-1or~-y

Try it online!

It turns out shorter to generate 2**n minus each term in the sequence for input n. If we look at their binary expansion, below for n=5, we see a nice pattern of triangles of 1's in the binary expansions.

100000 32
011111 31
011110 30
011100 28
011000 24
010000 16
001111 15
001110 14
001100 12
001000 8
000111 7
000110 6
000100 4
000011 3
000010 2
000001 1

Each number is obtained from the previous one by removing the rightmost one in the binary expansion, except if that would make the number 0, we subtract 1 instead, creating a new block of 1's that starts a new smaller triangle. This is implemented as y=y&y-1or~-y, where y&y-1 is a bit trick to remove the rightmost 1, and or~-y gives y-1 instead if that value was 0.

Python 2, 49 bytes

def f(n,x=0):1%n;print x;f(n-x%2,x+(x%2**n or 1))

Try it online!

A function that prints, terminating with error. The more nice program below turned out longer.

51 bytes

n=input()
x=0
while n:n-=x%2;print x;x+=x%2**n or 1

Try it online!

answered Sep 7, 2019 at 0:07
\$\endgroup\$
6
\$\begingroup\$

Jelly, (削除) 11 (削除ここまで) 10 bytes

RUḶ’F2*ĊÄŻ

Port of @Grimy's 05AB1E answer, so make sure to upvote him!
-1 byte thanks to @Grimy.

Try it online.

Explanation:

R # Create a list in the range [1, (implicit) argument]
 U # Reverse it to [argument, 1]
 Ḷ # Create an inner list in the range [0, N) for each value N in this list
 ’ # Decrease each by 1
 F # Flatten the list of lists
 2* # Take 2 to the power each
 Ċ # Ceil
 Ä # Undelta (cumulative sum) the list
 Ż # And add a leading 0
 # (after which the result is output implicitly)
answered Sep 6, 2019 at 13:35
\$\endgroup\$
2
  • 2
    \$\begingroup\$ R_2 -> Ḷ’ for -1. is the only sensible range, I really wish 05AB1E had a single-byter for it. \$\endgroup\$ Commented Sep 6, 2019 at 15:29
  • \$\begingroup\$ @Grimy Ah, how did I miss that one. I searched for range and must have skipped passed it somehow.. >.> Thanks! \$\endgroup\$ Commented Sep 6, 2019 at 16:27
4
\$\begingroup\$

Perl 5 (-n), (削除) 41 (削除ここまで) 40 bytes

-1 byte thanls to Xcali

map{/01.*1/||say oct}glob"0b"."{0,1}"x$_

TIO

  • "{0,1}"x$_ : the string "{0,1}" repeated n times
  • "0b". : concatenate to "0b"
  • glob : glob expansion (cartesian product)
  • map{...} : for each element
  • /01.*1/|| : to skip when 01 followed by something then 1
  • say oct : to convert to decimal and say
answered Sep 6, 2019 at 10:33
\$\endgroup\$
1
  • \$\begingroup\$ 40 \$\endgroup\$ Commented Sep 6, 2019 at 14:37
4
\$\begingroup\$

JavaScript (ES6), 43 bytes

When in doubt, use xnor's method.

n=>(g=x=>x?[n-x,...g(x&--x||x)]:[])(n=1<<n)

Try it online!


JavaScript (ES6), (削除) 59 57 55 (削除ここまで) 52 bytes

f=(n,x=0)=>x>>n?[]:[x,...f(n,x+=x+(x&=-x)>>n|!x||x)]

Try it online!

How?

We define \$p(x)\$ as the highest power of \2ドル\$ dividing \$x\$, with \$p(0)=0\$ by convention.

This function can be implemented with a simple bitwise AND of \$x\$ and \$-x\$ to isolate the lowest bit set to \1ドル\$ in \$x\$. For instance:

$$p(52)=52 \operatorname{AND}-52=4$$

Using \$p\$, the sequence \$a_n\$ can be defined as \$a_n(0)=0\$ and:

$$a_n(k+1)=\cases{ a_n(k)+p(a_n(k)), & \text{if $p(a_n(k))\neq0$ and $a_n(k)+p(a_n(k))<2^n$}\\ a_n(k)+1, & \text{otherwise} }$$

Commented

f = ( // f is a recursive function taking:
 n, // n = input
 x = 0 // x = current term of the sequence
) => //
 x >> n ? // if x is greater than or equal to 2**n:
 [] // stop recursion
 : // else:
 [ // update the sequence:
 x, // append the current term to the sequence
 ...f( // do a recursive call:
 n, // pass n unchanged
 x += // update x:
 x + (x &= -x) // given x' = lowest bit of x set to 1:
 >> n // if x + x' is greater than or equal to 2**n
 | !x // or x' is equal to 0: add 1 to x
 || x // otherwise, add x' to x
 ) // end of recursive call
 ] // end of sequence update
answered Sep 6, 2019 at 11:25
\$\endgroup\$
3
\$\begingroup\$

Python 2, (削除) 95 (削除ここまで) 76 bytes

n=input()
a=0
print 0
while n:
 for j in range(n):print a+2**j
 n-=1;a+=2**n

Try it online!

answered Sep 6, 2019 at 10:03
\$\endgroup\$
3
\$\begingroup\$

Perl 6, 43 bytes

{0 x$_,{say :2($_);S/(0)1|0$/10ドル/}...1 x$_}

Try it online!

Anonymous code block that takes a number and outputs the sequence separated by newlines. This works by starting with 0 repeated n times then replacing either 01 with 10 or the last 0 with a 1 until the number is just ones.

Or 40 bytes, using Nahuel Fouilleul's approach

{grep /010*1/|{say :2($_)},[X~] ^2 xx$_}

Try it online!

answered Sep 6, 2019 at 10:44
\$\endgroup\$
1
  • \$\begingroup\$ "then replacing either 01 with 10 or the last 0 with a 1 until the number is just ones" That's a genius move! \$\endgroup\$ Commented Sep 6, 2019 at 10:51
3
\$\begingroup\$

Python 2, 60 bytes

f=lambda i,n=0,b=1:[n][i:]or[n]+f(i-1/b,n^b+b/2,b>>i or 2*b)

Try it online!


Python 3, 76 bytes

f=lambda n:[0][n:]or[0]+[2**i for i in range(n-1)]+[x|1<<n-1for x in f(n-1)]

Try it online!

answered Sep 6, 2019 at 11:11
\$\endgroup\$
3
\$\begingroup\$

Python 2, 67 bytes

n=0
i=2**input()-1
while n<=i:print n;d=n&(~-n^i)or 1;n+=n+d>i or d

Try it online!

answered Sep 6, 2019 at 10:38
\$\endgroup\$
3
\$\begingroup\$

Python 3, 62 bytes

def f(n,c=0):
 while c<2**n:yield c;r=c&-c;c+=c+r>>n or r or 1

Try it online!

The idea is more or less the same as @Arnauld's solution.

Another 65-byte solution:

lambda n:g(2**n-1)
g=lambda c:[0][c:]or g(c-((c&-c)//2 or 1))+[c]

Try it online!

answered Sep 6, 2019 at 21:21
\$\endgroup\$
2
\$\begingroup\$

Jelly, 12 bytes

=þ‘ṚÄUo€ƊẎQḄ

Try it online!

answered Sep 6, 2019 at 12:27
\$\endgroup\$
2
\$\begingroup\$

05AB1E, (削除) 13 (削除ここまで) 12 bytes

Tsãʒ1ÛSO2‹}C{

-1 byte thanks to @Grimy (also take a look at his shorter approach here).

Try it online or verify all test cases.

Explanation:

T # Push 10
 sã # Swap to get the (implicit) input, and get the cartesian product with "10"
 ʒ # Filter it by:
 1Û # Remove leading 1s
 SO # Get the sum of the remaining digits
 ! # Check that the sum is either 0 or 1 by taking the factorial
 # (NOTE: Only 1 is truthy in 05AB1E)
 }C # After the filter: convert all remaining strings from binary to integer
 { # And sort (reverse) them
 # (after which the result is output implicitly)
answered Sep 6, 2019 at 11:59
\$\endgroup\$
7
  • \$\begingroup\$ Alternate 13: oL<ʒbIj1Û1¢2‹. Doesn't look like I can get it lower. \$\endgroup\$ Commented Sep 6, 2019 at 13:03
  • 1
    \$\begingroup\$ @Grimy I just had oL<ʒbIj1ÛSO2‹ and was trying to see where my error was. :) But I'm glad to see you aren't able to find a shorter version for one of my answers for a change. ;p (inb4 you find a shorter one after all xD) \$\endgroup\$ Commented Sep 6, 2019 at 13:06
  • 1
    \$\begingroup\$ @Grimy I have the feeling SO2‹ can be 3 bytes somehow perhaps, but I'm not seeing it and also not entirely sure.. There are some alternatives, like SO1~ or SÆ>d, but I'm unable to find a 3-byter. \$\endgroup\$ Commented Sep 6, 2019 at 13:13
  • 1
    \$\begingroup\$ 10 with a completely different approach \$\endgroup\$ Commented Sep 6, 2019 at 13:13
  • 1
    \$\begingroup\$ Your feeling was right, I just found a 3-byter: SO!. Pretty sure I have some old answers using 2‹ that could benefit from this as well. \$\endgroup\$ Commented Sep 6, 2019 at 13:45
2
\$\begingroup\$

Retina, 26 bytes

.+
*0
L$w`.(.*)
$.`*1$'11ドル

Try it online! Outputs in binary. If that's not acceptable, then for 39 bytes:

.+
*0
L$w`.(.*)
$.`*1$'11ドル
+`10
011
%`1

Try it online! Explanation:

.+
*0

Convert the input into a string of n zeros.

L$w`.(.*)

Match all possible non-empty substrings.

$.`*1$'11ドル

For each substring, output: the prefix with 0s changed to 1s; the suffix; the match with the initial 0 changed to 1.

+`10
011
%`1

Convert from binary to decimal.

answered Sep 6, 2019 at 22:21
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 27 bytes

1;0|⟦5;2z^(mLtT&-1↰+m↙T,L,0

Try it online!

Outputs out of order and with duplicates. If that's not okay, tack do onto the end.

answered Sep 8, 2019 at 5:11
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 19 bytes

I⮌E⊕θEι+−X2IθX2ιX2λ

Try it online! Link is to verbose version of code. Explanation:

 θ Input
 ⊕ Incremented
 E Map over implicit range
 ι Outer index
 E Map over implicit range
 Iθ Input cast to integer
 ι Outer index
 λ Inner index
 X2 X2 X2 Power of 2
 +− Subtract and add
 ⮌ Reverse outer list
I Cast to string
 Implicitly print
answered Sep 6, 2019 at 12:34
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 40 bytes

map{say$-;$-+=2**$_}0,0..$_-2;$_--&&redo

Try it online!

answered Sep 6, 2019 at 13:36
\$\endgroup\$
1
\$\begingroup\$

Retina, 24 bytes

.+
*0
/0/+<0`(0)1|0$
11ドル

Outputs in binary. Input should have a trailing newline.

Attempt at explanation:

.+ #match the entire input
*0 #replace it with that many zeroes
/0/+<0`(0)1|0$ #while the string has a 0, substitute the first match and output
11ドル #if 01 is present in the string, replace it with 10, else replace the last character with $

I tried to avoid the 3 bytes long /0/ regex option by rearranging the options, but couldn't.

Try it online!

answered Sep 7, 2019 at 6:10
\$\endgroup\$
1
  • \$\begingroup\$ I don't think outputting in binary is allowed. There's a comment asking if it is allowed, but it's better to assume that you can't until the asker replies \$\endgroup\$ Commented Sep 7, 2019 at 12:00
1
\$\begingroup\$

C (clang), 73 bytes

o,j,y;f(x){for(o=j=0;printf("%d ",o),x;o+=y+!y,y+=y+!y)j=!j?y=0,--x:--j;}

Try it online!

for(o=j=0;printf("%d ",o),x; o+=y+!y, y+=y+!y) 
// adds 1, 1+1=>2 , 2+2=> 4 .... sequence
 j=!j?y=0,--x:--j; 
// uses ternary instead of nested loop to decrement 'x' when 'j' go to 0
answered Sep 13, 2019 at 14:26
\$\endgroup\$
1
\$\begingroup\$

k4, (削除) 28 (削除ここまで) 24 bytes

0,+\"j"2ドル xexp,/-1+|,\!:

@Grimy's approach ported to k4

edit: -4 thanks to ngn!

answered Sep 13, 2019 at 15:11
\$\endgroup\$
3
  • 1
    \$\begingroup\$ !:'1+|!: -> |,\!: \$\endgroup\$ Commented Sep 16, 2019 at 16:19
  • \$\begingroup\$ you can remove the space after xexp \$\endgroup\$ Commented Sep 16, 2019 at 16:21
  • \$\begingroup\$ @ngn, agh |,\!: seems so obvious now that i see it! \$\endgroup\$ Commented Sep 17, 2019 at 10:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.