Números binarios en pendiente

15

Dado un número entero n, genera los primeros nnúmeros binarios inclinados, ya sea 0 o 1 indexados. Se llaman así por cómo se generan:

Escriba números en binario uno debajo del otro (justificado a la derecha):

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

Luego, debe tomar cada diagonal de abajo a la izquierda a arriba a la derecha, de modo que cada dígito final sea el último dígito de una diagonal. Aquí está la cuarta diagonal (indexada a cero) marcada con x's, que es 100:

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

Las diagonales ascendentes en orden son:

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

Luego, convertir a decimal, dando 0, 3, 6, 5, 4, 15, 10, ...

OEIS A102370

Este es el , por lo que gana el código más corto en bytes.

mbomb007
fuente
12
No creo que esta especificación sea muy clara. Tuve que hacer una buena cantidad de lecturas externas antes de poder entender lo que se preguntaba aquí.
Post Rock Garf Hunter
1
Aquí hay una visualización, si ayuda. Lea los "óvalos" de arriba a abajo y dentro del óvalo de abajo a la izquierda a la derecha. Esos le dan los números binarios que necesita convertir a decimal.
Pavel
¿Qué quieres decir con " indexado 0 o 1 "? ¿Quiere decir que uno puede generar el primer no el primer n+1número?
sonrisas
44
Creo que esto podría haber permitido respuestas más interesantes si solo tuvieras que devolver el enésimo valor.
xnor
1
@PatrickRoberts Nunca puse un límite en cuántos generar. Simplemente dije "escribir números en binario ...". Generas tantos como necesites.
mbomb007

Respuestas:

3

Jalea, 11 bytes

ḤḶBUz0ŒDUḄḣ

Pruébalo en línea!

Explicación

ḤḶ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.

La transposición es la forma más sencilla de rellenar la matriz para que funcionen las diagonales incorporadas. Luego se agregan los reveses para obtener todo en el orden correcto.

PurkkaKoodari
fuente
La implementación de la fórmula OEIS también podría ser realmente corta en Jelly.
Yytsi
@TuukkaX Podría ser. Estoy lo suficientemente cansado como para encontrar difícil elegir un límite superior para la suma.
PurkkaKoodari
@ TuukkaX Lo intenté, pero no veo que suceda. Estoy seguro de que Dennis & co lo implementará en 5 bytes más o menos.
PurkkaKoodari
Actualmente tienes suerte ;)
geisterfurz007
7

JavaScript (ES6), 53 bytes

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

0 indexado. No es frecuente que use una función recursiva como parámetro para map.

Neil
fuente
4

Mathematica, 46 bytes

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

Función sin nombre que toma un entero no negativo #como entrada y devuelve la secuencia de índice 0 hasta el #término enésimo. Construye los números binarios en pendiente usando BitAnd(bit a bit "y") con potencias apropiadas de 2.

Greg Martin
fuente
2

Python3, 63 61 bytes

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

Utiliza la fórmula de OEIS.

-2 bytes gracias a Luis Mendo ! i+1->i

Yytsi
fuente
¿Puedes explicar cómo pasaste Sum_{ k >= 1 such that n + k == 0 mod 2^k } 2^ka esa fórmula bit a bit más simple?
sonríe el
@smls Simplemente calcula las diagonales ascendentes directamente. De hecho, pensé que era más obvio que la otra forma.
Neil
1

PHP, 68 bytes

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

toma datos del argumento de la línea de comando, imprime números separados por guiones bajos. Corre con -r.

Titus
fuente
1

MATL , 18 17 bytes

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

Pruébalo en línea!

Esto usa la fórmula de OEIS:

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

Código:

: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
fuente
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..$_},^$_}

Utiliza la fórmula de la página OESIS.
Actualización: Cambió a la fórmula basada en bits de la respuesta Python de TuukkaX .

Perl 6 , 67 bytes

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

Solución ingenua.
Convierte los números que forman parte de la diagonal a la base 2, toma el dígito correcto de cada uno y convierte el resultado a la base 10.

smls
fuente
0

Jalea , 15 bytes

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

Esto sería más corta que la otra respuesta Jelly si tuviéramos que imprimir sólo el n º plazo.

Pruébalo en línea!

Dennis
fuente
0

R, 66 bytes

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

Función sin nombre que usa la binfunción del miscFuncspaquete para calcular la longitud nrepresentada en binario y luego usar una de las fórmulas OEIS.

Billywob
fuente