Mappatura biiettiva da numeri interi a un numero variabile di bit


11

Un numero variabile di bit è un array di 0 o più bit. Così [0, 1]è un numero variabile di bit, ma lo è anche [].

Scrivi una funzione o un programma che, dato un numero intero non negativo, restituisca un numero variabile di bit in modo tale che ogni numero intero abbia una mappatura uno a uno (biiettiva) con un array.

Esistono un'infinità di tali mappature, sei libero di costruirne uno a tuo piacimento, ma deve essere uno a uno. Il tuo mapping deve essere concettualmente uno a uno per un numero intero di dimensioni arbitrarie, ma va bene se l' implementazione non riesce per numeri interi di grandi dimensioni a causa di limiti numerici di tipi nella tua lingua preferita (ad es. C int).

Come esempio di ciò che non è un mapping uno a uno, è semplicemente elencare le cifre binarie dell'intero. In un tale sistema 5 diventa [1, 0, 1](o 0b101), ma non è uno a uno, perché 0b0101o [0, 1, 0, 1]significa anche 5.

Dovrebbe essere abbastanza ovvio che un mapping non è uno a uno se salta un numero intero (ad esempio non funziona per 5), ma vorrei chiarire che saltare un array di bit variabile non è nemmeno uno -to-uno. È necessario eseguire il mapping a tutti i possibili array di bit variabili, incluso [].


Vince il codice più breve in byte.


Possiamo restituire una stringa di 0 e 1?
xnor

@xnor Sì, una stringa di 0 e 1 va bene.
orlp,

Risposte:


4

Gelatina, 3 byte

‘BḊ

Stessa idea di xnor: mappa 0 1 2 3 4 ...a [] [0] [1] [0 0] [0 1] ...; il codice è sostanzialmente increment → binary → remove first.

Provalo online .


10

Python, 20 byte

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

Test:

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

Fare lambda n:bin(n+1)[3:]incrementa l'input, quindi prende la rappresentazione binaria con il primo simbolo rimosso ( [3:]perché il prefisso 0bè due caratteri). Poiché qualsiasi numero positivo inizia con 1 in binario, ciò fornisce in modo univoco una rappresentazione binaria.

Un byte viene salvato invece utilizzando il complemento di bit ~nper ottenere la negazione -(n+1)e rimuovendo il segno negativo tagliando un altro simbolo.


1
Inverse: lambda s:int('1'+s,2)-1.
orlp,

2

Pyth, 5 byte

t.BhQ

Semplicemente una traduzione della risposta di xnor in Pyth.

Qè eval () 'd input (), lo hincrementa, lo .Bconverte in una stringa binaria e tprende la "coda" (che è tutto tranne il primo carattere).


2

Haskell, 41 38 30 29 byte

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

Esempio di utilizzo: (l!!) 4-> "10".

A partire dall'elenco vuoto come primo elemento, percorri pigramente l'elenco e aggiungi l'elemento corrente con 0e con 1davanti.

Modifica: @xnor ha salvato 3 11 byte. Grazie!


Idea interessante. La funzione ripetuta può essere scritta[(0:),(1:)]<*>
xnor

@xnor: Oh, mi hai mostrato il <*>trucco prima, ma me ne sono dimenticato. Grazie ancora!
nimi,

Ooh, è possibile definire l'intera lista pigramente: l=[]:[b:x|x<-l,b<-[0,1]];(l!!).
xnor

@xnor: Fantastico! Molte grazie! Oh, il passaggio alle stringhe consente di risparmiare un altro byte.
nimi,

Sento che dovrebbe esserci un modo più breve per esprimere [b:x|x<-l,b<-"01"]con un prodotto o una concat-map, ma l'espressione del prodotto (:)<$>[0,1]<*>lva nell'ordine sbagliato, prima anteponendo 0 a tutto, senza mai arrivare a 1 perché l'elenco è infinito. Hai qualche idea?
xnor

1

JavaScript (ES6), 29 byte

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

Stessa idea di xnor.

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


Questo è prontamente esteso ad altre basi come da codegolf.stackexchange.com/q/78990
Neil

1

Jolf, 4 byte

Provalo qui!

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

Strategia molto semplice, sembra anche essere la più breve.


1

Haskell, 35 byte

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

Haskell non ha un binario incorporato, quindi la conversione (invertita) viene eseguita manualmente. Per rimuovere 1 iniziale, il caso base è stato 1trasformato in un elenco vuoto.

Modifica: salvato un byte coniugando con +1invece.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.