Mapeo biyectivo de enteros a un número variable de bits

11

Un número variable de bits es una matriz de 0 o más bits. Entonces, [0, 1]es un número variable de bits, pero también lo es [].

Escriba una función o programa que, dado un número entero no negativo, devuelva un número variable de bits, de modo que cada número entero tenga un mapeo uno a uno (biyectivo) con una matriz.

Hay una cantidad infinita de tales mapeos, usted es libre de construir uno a su gusto, pero debe ser uno a uno. Su mapeo debe ser conceptualmente uno a uno para un número entero de tamaño arbitrario, pero está bien si su implementación falla para números enteros grandes debido a los límites numéricos de los tipos en su idioma preferido (por ejemplo, C int).

Como ejemplo de lo que no es un mapeo uno a uno, es simplemente enumerar los dígitos binarios del entero. En dicho sistema, 5 se convierte [1, 0, 1](o 0b101), pero no es uno a uno, porque 0b0101o [0, 1, 0, 1]también significa 5.

Debería ser bastante obvio que un mapeo no es uno a uno si omite un número entero (por ejemplo, no funciona para 5), ​​pero me gustaría dejar en claro que omitir una matriz de bits variable tampoco es uno -a uno. Debe asignar a cada matriz de bits variable posible, incluida [].


El código más corto en bytes gana.

orlp
fuente
¿Podemos devolver una cadena de 0 y 1?
xnor
@xnor Sí, una cadena de 0s y 1s está bien.
orlp

Respuestas:

4

Jalea, 3 bytes

‘BḊ

La misma idea que xnor: asigna 0 1 2 3 4 ...a [] [0] [1] [0 0] [0 1] ...; El código es básicamente increment → binary → remove first.

Pruébalo en línea .

Lynn
fuente
10

Python, 20 bytes

lambda n:bin(~n)[4:]

Prueba:

>> [bin(~n)[4:] for n in range(16)]
['', '0', '1', '00', '01', '10', '11', '000', '001', '010', '011', '100', '101', '110', '111', '0000']

Hacer lambda n:bin(n+1)[3:]incrementa la entrada, luego toma la representación binaria con el primer símbolo eliminado ( [3:]porque el prefijo 0bes dos caracteres). Dado que cualquier número positivo comienza con 1 en binario, esto únicamente da una representación binaria.

En su lugar, se guarda un byte utilizando el complemento de bits ~npara obtener la negación -(n+1)y eliminando el signo negativo cortando un símbolo más.

xnor
fuente
1
Inversa: lambda s:int('1'+s,2)-1.
orlp
2

Pyth, 5 bytes

t.BhQ

Simplemente una traducción de la respuesta de xnor a Pyth.

Qes eval () 'd input (), lo hincrementa, lo .Bconvierte en una cadena binaria y ttoma la "cola" (que es todo excepto el primer carácter).

Pomo de la puerta
fuente
2

Haskell, 41 38 30 29 bytes

l="":[b:x|x<-l,b<-"01"]
(l!!)

Ejemplo de uso: (l!!) 4-> "10".

Comenzando con la lista vacía como el primer elemento, recorra perezosamente la lista y agregue el elemento actual con 0y 1delante de él.

Editar: @xnor guardó 3 11 bytes. ¡Gracias!

nimi
fuente
Idea interesante. La función iterada se puede escribir[(0:),(1:)]<*>
xnor
@xnor: Oh, me enseñaste el <*>truco antes, pero lo olvidé. ¡Gracias de nuevo!
nimi
Ooh, puede definir la lista entera con pereza: l=[]:[b:x|x<-l,b<-[0,1]];(l!!).
xnor
@xnor: ¡Genial! ¡Muchas gracias! Oh, cambiar a cadenas ahorra un byte más.
nimi
Siento que debería haber una forma más corta de expresar [b:x|x<-l,b<-"01"]con un producto o concat-map, pero la expresión del producto (:)<$>[0,1]<*>lva en el orden incorrecto, anteponiendo primero 0 a todo, nunca llegando a 1 porque la lista es infinita. ¿Tienes alguna idea?
xnor
1

JavaScript (ES6), 29 bytes

x=>(~x).toString(2).slice(2)

La misma idea que xnor.

f=x=>(~x).toString(2).slice(2);
[...Array(100)].map((v,x)=>A.textContent+=x + ': ' + f(x) + '\n')
<pre id=A></pre>

andlrc
fuente
Esto se extiende fácilmente a otras bases según codegolf.stackexchange.com/q/78990
Neil
1

Jolf, 4 bytes

Pruébalo aquí!

wBhj
  hj  input + 1
 B    converted to binary
w     with first removed.

Estrategia muy simple, también resulta ser la más corta.

Conor O'Brien
fuente
1

Haskell, 35 bytes

h 1=[]
h n=mod n 2:h(div n 2)
h.(+1)

Haskell no tiene un binario incorporado, por lo que la conversión (invertida) se realiza manualmente. Para eliminar el 1 inicial, el caso base se 1transforma en la lista vacía.

Editar: guardado un byte conjugando con el +1en su lugar.

h 0=[]
h m=1-mod m 2:h(div(m+1)2-1)
xnor
fuente
1

C, 40 bytes

f(n){if(++n/2)putchar(n%2+48),f(n/2-1);}

Convierte la entrada a la base biyectiva 2 (con símbolos 0y 1), como las otras respuestas.

ideonelo!

un sustantivo delgado contratado
fuente