Mappage bijectif d'entiers à un nombre variable de bits


11

Un nombre variable de bits est un tableau de 0 ou plusieurs bits. Il en [0, 1]va de même pour un nombre variable de bits, mais il en est de même [].

Écrivez une fonction ou un programme qui, étant donné un entier non négatif, renvoie un nombre variable de bits de sorte que chaque entier ait un mappage un à un (bijectif) avec un tableau.

Il existe une quantité infinie de ces mappages, vous êtes libre d'en créer un à votre guise, mais ce doit être un à un. Votre mappage doit conceptuellement être un pour un pour un entier de taille arbitraire, mais c'est OK si votre implémentation échoue pour les grands entiers en raison des limites numériques des types dans votre langue préférée (par exemple, les C int).

À titre d'exemple de ce qui n'est pas un mappage un à un, il suffit de répertorier les chiffres binaires de l'entier. Dans un tel système, 5 devient [1, 0, 1](ou 0b101), mais ce n'est pas un à un, car 0b0101ou [0, 1, 0, 1]signifie également 5.

Il devrait être assez évident qu'un mappage n'est pas un à un s'il saute un entier (par exemple, il ne fonctionne pas pour 5), mais je tiens à préciser que sauter un tableau de bits variable n'est pas non plus un -à une. Vous devez mapper sur tous les tableaux de bits variables possibles, y compris [].


Le code le plus court en octets gagne.


Pouvons-nous renvoyer une chaîne de 0 et de 1?
xnor

@xnor Oui, une chaîne de 0 et de 1 suffit.
orlp

Réponses:


4

Gelée, 3 octets

‘BḊ

Même idée que xnor: correspond 0 1 2 3 4 ...à [] [0] [1] [0 0] [0 1] ...; le code est fondamentalement increment → binary → remove first.

Essayez-le en ligne .


10

Python, 20 octets

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

Tester:

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

Faire lambda n:bin(n+1)[3:]incrémente l'entrée, puis prend la représentation binaire avec le premier symbole supprimé ( [3:]car le préfixe 0best deux caractères). Étant donné que tout nombre positif commence par 1 en binaire, cela donne uniquement une représentation binaire.

Un octet est enregistré en utilisant à la place le complément de bits ~npour obtenir la négation -(n+1)et en supprimant le signe négatif en coupant un symbole de plus.


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

2

Pyth, 5 octets

t.BhQ

Simplement une traduction de la réponse de xnor en Pyth.

Qest eval () 'd input (), l' hincrémente, le .Bconvertit en une chaîne binaire et tprend la "queue" (qui est tout sauf le premier caractère).


2

Haskell, 41 38 30 29 octets

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

Exemple d'utilisation: (l!!) 4-> "10".

En commençant par la liste vide comme premier élément, parcourez la liste paresseusement et ajoutez l'élément actuel avec 0et avec 1devant.

Modifier: @xnor a enregistré 3 11 octets. Merci!


Idée intéressante. La fonction itérée peut être écrite[(0:),(1:)]<*>
xnor

@xnor: Oh, tu m'as déjà montré le <*>truc, mais je l'ai oublié. Merci encore!
nimi

Ooh, vous pouvez définir toute la liste paresseusement: l=[]:[b:x|x<-l,b<-[0,1]];(l!!).
xnor

@xnor: Super! Merci beaucoup! Oh, le passage aux chaînes enregistre un octet de plus.
nimi

Je pense qu'il devrait y avoir un moyen plus court d'exprimer [b:x|x<-l,b<-"01"]avec un produit ou une carte de concaténation, mais l'expression du produit (:)<$>[0,1]<*>lva dans le mauvais ordre, en ajoutant d'abord 0 à tout, jamais à 1 car la liste est infinie. As tu des idées?
xnor

1

JavaScript (ES6), 29 octets

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

Même idée que xnor.

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


Ceci est facilement étendu à d'autres bases selon codegolf.stackexchange.com/q/78990
Neil

1

Jolf, 4 octets

Essayez-le ici!

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

Stratégie très simple, se trouve également être la plus courte.


1

Haskell, 35 octets

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

Haskell n'a pas de binaire intégré, donc la conversion (inversée) se fait manuellement. Pour supprimer le 1 initial, le cas de base s'est 1transformé en liste vide.

Edit: enregistré un octet en conjuguant à la +1place.

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.