Sloping Binary Numbers

15

Given an integer n, output the first n sloping binary numbers, either 0- or 1-indexed. They are called this because of how they are generated:

Write numbers in binary under each other (right-justified):

........0
........1
.......10
.......11
......100
......101
......110
......111
.....1000
.........

Then, you need to take each diagonal from bottom-left to top-right, such that each final digit is the final digit of a diagonal. Here's the fourth diagonal (zero-indexed) marked with x's, which is 100:

........0
........1
.......10
.......11
......10x
......1x1
......x10
......111
.....1000
.........

The upward-sloping diagonals in order are:

0
11
110
101
100
1111
1010
.......

Then, convert to decimal, giving 0, 3, 6, 5, 4, 15, 10, ...

OEIS A102370

This is , so the shortest code in bytes wins.

mbomb007

Posted 2016-12-22T23:01:09.020

Reputation: 21 944

12I don't think this specification is very clear. I had to do a good deal of external reading before I could understand what was being asked here. – Post Rock Garf Hunter – 2016-12-22T23:13:27.597

1Here's a visualization, if it helps. Read the "ovals" top to bottom, and within the oval from bottom left to top right. Those give you the binary numbers you need to convert to decimal. – Pavel – 2016-12-22T23:35:47.253

What do you mean, "either 0- or 1-indexed"? Do you mean that one may output either the first n or the first n+1 numbers? – smls – 2016-12-22T23:49:18.070

@Flp.Tkc yes, thanks for pointing that out. I edited the question and tagged it as such. (not OP) – Rɪᴋᴇʀ – 2016-12-23T00:20:22.103

Hopefully I made it clearer. – mbomb007 – 2016-12-23T01:19:08.590

4I think this might have allowed more interesting answers if you just had to return the n'th value. – xnor – 2016-12-23T03:27:33.683

@xnor I thought people might just use the formula on OEIS either way. I didn't know which would be better. – mbomb007 – 2016-12-23T04:04:31.590

The specification makes sense to me, but if you're going to output the first N numbers sloped up like this, shouldn't you be generating the first N + binlen(N) or so numbers? – Patrick Roberts – 2016-12-23T18:09:56.593

1@PatrickRoberts I never put a limit on how many to generate. I simply said "write numbers in binary...". You generate as many as you need to. – mbomb007 – 2016-12-23T18:11:02.873

Answers

3

Jelly, 11 bytes

ḤḶBUz0ŒDUḄḣ

Try it online!

Explanation

ḤḶBUz0ŒDUḄḣ    Main link. Argument: n
Ḥ              Double the argument. This ensures there are enough
               rows, since n + log2(n) <= 2n.
 Ḷ             Get range [0 .. 2n-1].
  B            Convert each number to binary.
   U           Reverse each list of digits. 
    z0         Transpose, padding with zeroes to a rectangle.
      ŒD       Get the diagonals of the rectangle, starting from the
               main diagonal. This gets the desired numbers, reversed,
               in binary, with some extras that'll get dropped.
        U      Reverse each diagonal.
         Ḅ     Convert each diagonal from binary to a number.
          ḣ    Take the first n numbers.

The transpose is the simplest way to pad the array for the diagonals builtin to work. Then the reverses are added to get everything in the correct order.

PurkkaKoodari

Posted 2016-12-22T23:01:09.020

Reputation: 16 699

The implementation of the OEIS formula might also be really short in Jelly. – Yytsi – 2016-12-23T00:04:52.993

@TuukkaX Might be. I'm tired enough to find picking an upper limit for the sum hard. – PurkkaKoodari – 2016-12-23T00:19:22.317

@TuukkaX I tried it, but I don't see it happening. I'm sure Dennis & co will implement it in 5 bytes or so. – PurkkaKoodari – 2016-12-23T00:52:07.897

Currently you are lucky ;)

– geisterfurz007 – 2016-12-23T06:16:58.097

7

JavaScript (ES6), 53 bytes

n=>[...Array(n)].map(g=(j=1,i)=>j>i?0:j&i|g(j+j,i+1))

0-indexed. It's not often I get to use a recursive function as a parameter to map.

Neil

Posted 2016-12-22T23:01:09.020

Reputation: 95 035

4

Mathematica, 46 bytes

Plus@@@Table[BitAnd[n+k,2^k],{n,0,#},{k,0,n}]&

Unnamed function taking a nonnegative integer # as input and returning the 0-index sequence up to the #th term. Constructs the sloping binary numbers using BitAnd (bitwise "and") with appropriate powers of 2.

Greg Martin

Posted 2016-12-22T23:01:09.020

Reputation: 13 940

2

Python3, 63 61 bytes

lambda i:[sum(n+k&2**k for k in range(n+1))for n in range(i)]

Uses the formula from OEIS.

-2 bytes thanks to Luis Mendo! i+1 --> i

Yytsi

Posted 2016-12-22T23:01:09.020

Reputation: 3 582

Can you explain how you went from Sum_{ k >= 1 such that n + k == 0 mod 2^k } 2^k to that simpler bitwise formula? – smls – 2016-12-23T00:36:06.717

@smls It just calculates the upward diagonals directly. I actually thought it was more obvious than the other form. – Neil – 2016-12-23T00:41:27.193

1

MATL, 18 17 bytes

:q"@tt:+5MW\~fWs+

Try it online!

This uses the formula from OEIS:

a(n) = n + Sum_{ k in [1 2... n] such that n + k == 0 mod 2^k } 2^k

Code:

:q"     % For k in [0 1 2 ...n-1], where n is implicit input
  @     %   Push k
  tt    %   Push two copies
  :     %   Range [1 2 ... k]
  +     %   Add. Gives [n+1 n+2 ... n+k]
  5M    %   Push [1 2... k] again
  W     %   2 raised to that
  \     %   Modulo
  ~f    %   Indices of zero entries
  W     %   2 raised to that
  s     %   Sum of array
  +     %   Add
        % End implicitly. Display implicitly

Luis Mendo

Posted 2016-12-22T23:01:09.020

Reputation: 87 464

1

PHP, 68 bytes

for(;$n++<$argv[1];print$s._)for($s=$i=0;$i<$n;)$s|=$n+$i-1&1<<$i++;

takes input from command line argument, prints numbers separated by underscores. Run with -r.

Titus

Posted 2016-12-22T23:01:09.020

Reputation: 13 814

0

Perl 6, 59 43 bytes

{map ->\n{n+sum map {2**$_ if 0==(n+$_)%(2**$_)},1..n},^$_}

{map {sum map {($_+$^k)+&2**$k},0..$_},^$_}

Uses the formula from the OESIS page.
Update: Switched to the bitwise-and based formula from TuukkaX's Python answer.

Perl 6, 67 bytes

{map {:2(flip [~] map {.base(2).flip.comb[$++]//""},$_..2*$_)},^$_}

Naive solution.
Converts the numbers that are part of the diagonal to base 2, takes the correct digit of each, and converts the result back to base 10.

smls

Posted 2016-12-22T23:01:09.020

Reputation: 4 352

0

Jelly, 15 bytes

2*ḍ+
ḶçЀḶUḄ+Ḷ’

This would be shorter than the other Jelly answer if we had to print only the nth term.

Try it online!

Dennis

Posted 2016-12-22T23:01:09.020

Reputation: 196 637

0

R, 66 bytes

function(n,k=0:length(miscFuncs::bin(n-1)))sum(bitwAnd(k+n-1,2^k))

Unnamed function which uses the bin function from the miscFuncs package to calculate the length of n represented in binary and then using one of the OEIS formulas.

Billywob

Posted 2016-12-22T23:01:09.020

Reputation: 3 363