Mapeamento bijetivo de números inteiros para um número variável de bits

11

Um número variável de bits é uma matriz de 0 ou mais bits. Então, [0, 1]é um número variável de bits, mas assim é [].

Escreva uma função ou programa que, dado um número inteiro não negativo, retorne um número variável de bits, de modo que todo número inteiro tenha um mapeamento um para um (bijetivo) com uma matriz.

Há uma quantidade infinita desses mapeamentos, você pode criar um como quiser, mas deve ser um a um. Conceitualmente, seu mapeamento deve ser individual para um número inteiro de tamanho arbitrário, mas tudo bem se sua implementação falhar para números inteiros grandes devido a limites numéricos de tipos no seu idioma preferido (por exemplo, C's int).

Como exemplo do que não é um mapeamento um para um, basta listar os dígitos binários do número inteiro. Nesse sistema, 5 se torna [1, 0, 1](ou 0b101), mas não é um para um, porque 0b0101ou [0, 1, 0, 1]também significa 5.

Deveria ser óbvio que um mapeamento não é individual se pular um número inteiro (por exemplo, não funciona para 5), ​​mas eu gostaria de deixar claro que ignorar uma matriz de bits variável também não é uma. -para um. Você deve mapear a cada matriz de bits variável possível, inclusive [].


código mais curto em bytes vitórias.

orlp
fonte
Que possamos retornar uma seqüência de 0 e 1 de?
xnor
@ xnor Sim, uma sequência de 0s e 1s é boa.
orlp

Respostas:

4

Geléia, 3 bytes

‘BḊ

Mesma idéia que xnor: mapeia 0 1 2 3 4 ...para [] [0] [1] [0 0] [0 1] ...; o código é basicamente increment → binary → remove first.

Experimente online .

Lynn
fonte
10

Python, 20 bytes

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

Teste:

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

Fazer lambda n:bin(n+1)[3:]incrementa a entrada e, em seguida, pega a representação binária com o primeiro símbolo removido ( [3:]porque o prefixo 0bé dois caracteres e caracteres). Como qualquer número positivo começa com 1 em binário, isso fornece exclusivamente uma representação binária.

Um byte é salvo usando o complemento de bits ~npara obter a negação -(n+1)e removendo o sinal negativo cortando mais um símbolo.

xnor
fonte
1
Inverso: lambda s:int('1'+s,2)-1.
orlp
2

Pitão, 5 bytes

t.BhQ

Simplesmente uma tradução da resposta de xnor para Pyth.

Qis eval () 'd input (), hincrementa-o, .Bconverte-o em uma string binária e tpega o "tail" (que é tudo, exceto o primeiro caractere).

Maçaneta da porta
fonte
2

Haskell, 41 38 30 29 bytes

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

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

Começando com a lista vazia como o primeiro elemento, percorra vagarosamente a lista e acrescente o elemento atual com 0e com 1na frente dele.

Edit: @xnor salvou 3 11 bytes. Obrigado!

nimi
fonte
Idéia interessante. A função iterada pode ser gravada[(0:),(1:)]<*>
xnor
@xnor: Oh, você me mostrou o <*>truque antes, mas eu esqueci o assunto. Obrigado novamente!
nimi
Ooh, você pode definir toda a lista preguiçosamente: l=[]:[b:x|x<-l,b<-[0,1]];(l!!).
xnor
@xnor: Ótimo! Muito obrigado! Ah, mudar para strings economiza mais um byte.
nimi
Eu sinto que deveria haver uma maneira mais curta de expressar [b:x|x<-l,b<-"01"]com um produto ou mapa de concat, mas a expressão do produto (:)<$>[0,1]<*>lestá na ordem errada, primeiro acrescentando 0 a tudo, nunca chegando a 1 porque a lista é infinita. Você tem alguma ideia?
xnor
1

JavaScript (ES6), 29 bytes

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

Mesma idéia 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
fonte
Isso é prontamente estendido para outras bases, conforme codegolf.stackexchange.com/q/78990 #
Neil
1

Jolf, 4 bytes

Experimente aqui!

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

Estratégia muito simples, também é a mais curta.

Conor O'Brien
fonte
1

Haskell, 35 bytes

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

O Haskell não possui um binário interno, portanto a conversão (reversa) é feita manualmente. Para remover o 1 inicial, o caso base foi 1transformado na lista vazia.

Editar: Salva um byte conjugando com o +1invés.

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

C, 40 bytes

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

Converte a entrada na base bijetiva 2 (com símbolos 0e 1), como as outras respostas.

ideone isso!

um substantivo slim contratado
fonte