Écrivez le code le plus court pour inverser l'ordre des bits d'un entier 32 bits.
Règles:
- L'entrée est supposée être un entier ou une chaîne équivalente valide si votre langue ne prend pas en charge les valeurs numériques (par exemple, Windows Batch).
- La sortie doit être un entier ou une chaîne équivalente valide si votre langue ne prend pas en charge les valeurs numériques (par exemple, Windows Batch).
- Bibliothèque standard uniquement.
- Il peut s'agir d'une fonction ou d'un programme complet.
- L'entrée peut provenir de
stdin
ou comme argument de fonction. - La sortie doit être soit
stdout
ou comme valeur retournée. - Si votre langue a une fonction de bibliothèque intégrée ou standard qui le fait en une seule étape (par exemple
rbit
dans l'assemblage ARM), cela ne peut pas être utilisé.
Exemples:
Clé:
- décimal
- binaire
- (sens inverse)
- binaire inversé
- sortie décimale
Exemples:
-90
(Exemple 8 bits pour démonstration)10100110b
- (sens inverse)
01100101b
101
486
00000000000000000000000111100110b
- (sens inverse)
01100111100000000000000000000000b
1736441856
-984802906
11000101010011010001100110100110b
- (sens inverse)
01100101100110001011001010100011b
1704506019
Remarque: les omissions sont un jeu gratuit. Si je ne l'ai pas dit et que ce n'est pas une des failles standard , alors c'est complètement autorisé.
Réponses:
assemblage x86, 9 octets
Sous forme d'
33 C0 40 D1 E9 13 C0 73 FA
octets:, 9 octets.la source
__fastcall
et je n'en avais pasret
.Assemblage MMIX (28 octets)
Nombres 64 bits
Cela s'assemble pour:
Comment ça marche?
L'
MOR
instruction effectue une multiplication matricielle sur deux quantités 64 bits utilisées comme deux matrices 8x8 de booléens. Un nombre booléen avec des chiffres abcdefghklmnopqr 2 est utilisé comme matrice comme ceci:L'
MOR
instruction multiplie les matrices représentées par leurs arguments où la multiplication estand
et l'addition estor
. Il est:et en plus:
qui est l'ordre inverse des bits du nombre d'origine.
Nombres de 32 bits
Si vous voulez juste l'inverse d'un nombre 32 bits au lieu d'un nombre 64 bits, vous pouvez utiliser cette méthode modifiée:
assemblé:
La première multiplication matricielle fonctionne essentiellement comme ceci:
l'octaoctet correspondant est celui
#0000000001020408
que nous chargeons dans les deux premières instructions. La deuxième multiplication ressemble à ceci:L'octaoctet correspondant est celui
#0102040810204080
que nous créons à partir de la première matrice comme ceci:La deuxième multiplication est comme d'habitude, le code résultant a la même longueur (28 octets).
la source
POLY
instruction du VAX est fondamentalement une multiplication et une addition fusionnées avec une boucle intégrée. Des choses similaires existent également dans les architectures modernes (comme x86), mais elles n'ont généralement pas de boucle intégrée pour évaluer un polynôme entier à la fois.Assemblage 80386 (
1312 octets)En tant que fonction dans la syntaxe AT&T en utilisant la convention d'appel cdecl.
Cette fonction s'assemble à la séquence d'octets suivante:
Décomposé en instructions:
Cela fonctionne comme ceci: dans chacune des 32 itérations de la boucle, l'argument, qui est situé à
4(%esp)
, est décalé vers la droite d'une position. Le dernier bit est implicitement décalé dans le drapeau de retenue. L'adc
instruction ajoute deux valeurs et ajoute la valeur de l'indicateur de report au résultat. Si vous ajoutez une valeur à elle-même, c'est-à-dire que%eax
vous la décalez effectivement vers la gauche d'une position. Cela constitueadc %eax,%eax
un moyen pratique de décaler vers la gauche%eax
d'une position tout en décalant le contenu du drapeau de report dans le bit de poids faible.Je répète ce processus 32 fois pour que tout le contenu de
4(%esp)
soit vidé%eax
. Je n'initialise jamais explicitement%eax
car son contenu précédent est déplacé pendant la boucle.la source
C,
635248Version originale:
Version mise à jour (avec des modifications suggérées par Allbeert , es1024 et Dennis ):
Remarque: Étant donné que la deuxième version omet le paramètre
r=0
, le code suppose que anint
vaut 32 bits. Si cette hypothèse est fausse, la fonction produira très probablement un résultat incorrect, selon l'état initialr
lors de l'entrée dans la fonction.Version finale (avec d'autres modifications suggérées par Dennis et Alchymist ):
Remarque: Cela place la déclaration des variables de travail
r
eti
dans la liste des paramètres. Les paramètres sont les suivants:n
est le nombre à inverser en bits.r
eti
sont des variables de travail qui doivent être passées à 0.la source
int
type de fonction et également changerreturn r
pour quelque chose comme,i=r
car la plupart des compilateurs C ont tendance à laisser le résultat de la dernière opération dans le registre de retour. Cela a fonctionné sur gcc et cl pour moi.r(n){...}
au lieu der(int n){...}
int
àint r=0,i=32;
moins de le déplacer hors du corps de la fonction.-1 >> 1
est-1
pour AS et2**31 - 1
pour LS, tandis que-1 / 2
est0
.r
eti
comme arguments? Économiserait trois octets de plus ...Julia 0,2, 33 octets
Fait à quoi ça ressemble.
bits
vous donne la représentation des bits (en respectant le complément à deux).parseint
ne se soucie pas du complément à deux, mais renvoie un entier 32 bits, donc le complément à deux est simplement géré par débordement.Selon les changelogs, la détection de débordement a été ajoutée
parseint
dans Julia 0.3, donc cela pourrait ne plus fonctionner.la source
Python 2, 50
Généralement la même que ma solution Pyth. Prenez le mod d'entrée 2 ** 32, convertissez en binaire rembourré 32 bits, inversez, convertissez la piqûre binaire en décimal et imprimez.
la source
CJam, 15 octets
Essayez-le en ligne.
Joker "jeu gratuit" utilisé: La sortie sera toujours un entier non signé .
Cas de test
Comment ça marche
la source
JavaScript (E6) 37
39 40 50Fonction, entrée de numéro et retour d'un numéro inversé.
L'algorithme le plus basique peut probablement être joué plus avec une astuce intelligente.Modifier la récursivité au lieu de la boucle
Modifier 2 Suivant la suggestion @bebe
k*2
au lieu dek<<1
Edit 3 Quelque chose que j'avais manqué du tout: c'est une boucle complète de 32 bits, pas besoin d'initialiser k. Merci @FUZxxl
C'était
Testez dans la console FireFox, testez en utilisant des nombres dans OP et quelques autres nombres aléatoires de 16 et 32 bits
Exemple de sortie de test
la source
b=k=0,R=v=>b++<32?R(v>>1,k+=k+(v&1)):k
à usage unique etR=(v,b=0,k=0)=>b<32?R(v>>1,b+1,k+k+(v&1)):k
est réutilisablek<<1
devientk*2
etv>>1
devientv/2
. cela a fonctionné pour 486. je ne sais pas d'autres cas de testAssemblage x86, 10 octets
Cela suppose une entrée dans eax, une sortie dans edx. (En outre, à la sortie, eax est nul et CF et ZF sont définis, si quelqu'un s'en soucie).
Au lieu d'un compteur, un 1 supplémentaire est inséré au début comme marqueur de fin de données
la source
ret
instruction de retour de la fonction et implémentez cdecl (c'est-rcr %eax
à- dire changez versrcr 4(%esp)
etrcl %edx
versrcl %eax
), vous vous retrouvez avec un octet supplémentaire pour leret
et deux autres octets pour la référence mémoire. Pourtant, une belle solution.J (
171513 octets)Voici une définition explicite pour expliquer ce qu'il fait:
#: y
représentey
un nombre de base 2 en utilisant autant d'emplacements que nécessaire.x {. y
prend|x
(magnitude dex
) les éléments dey
, de l'avant six
est positif, de l'arrière six
est négatif. Si nous prenons plus d'articles que présents, le résultat est rempli de zéros._32 {. #: y
tamponne efficacement#: y
à 32 bits.|. y
flipsy
, i. inverse l'ordre des éléments dansy
.#. y
interprètey
comme un nombre de base 2.la source
Dyalog APL , 10 octets
2⊥
de-base-2 de⌽
l'inverse⎕
entrée numérique⊤⍨
dans le système de numérotation composé de32/2
32 bitsTryAPL en ligne!
la source
Python - 89
Python représente simplement les nombres binaires négatifs
-0b{positive_number}
. Donc, pour faire face à cela, complétez les nombres négatifs puis XOR avec tous les 1.Après cela, créez la représentation sous forme de chaîne de l'entier en fonction du format
{:032b}
qui fournit la représentation 32 bits du nombre. Enfin, inversez la chaîne et retournez-la en entier.MODIFIER
Merci à @Martin Büttner d' avoir signalé un problème de complément à deux. Si
n
se termine par un 1, alors par un complément à deux, la version inversée serait négative.Heureusement, comme expliqué ci-dessus, Python aime les nombres binaires négatifs d'une manière assez simple. Heureusement aussi, la
int
fonction de Python autorise les caractères de signe facultatifs dans son premier argument.Alors maintenant, ajoutez un signe moins si
n
est impair pour satisfaire le complément à deux.la source
['','-'][n%2]
c'est'-'*(n%2)
.Pyth ,
333222Explication:
Golfs:
33 -> 32: Déplacer l'ajout à avant d'inverser pour enregistrer un devis final.
32 -> 22: Q mod 2 ^ 32 d'occasion au lieu de machines compliquées. Combiné les deux chaînes en une seule.
Cas de test:
la source
GNU dc, 27 octets
Sortie:
Bash + coreutils, 45 octets
Sortie:
Fonction C, 89 octets
Même idée que /codegolf//a/36289/11259 - en utilisant les hacks twiddling de Stanford . Ne va pas gagner le golf, mais intéressant quand même:
Sortie:
la source
Fonction Java, 64 caractères.
Devrait également fonctionner en C.
la source
PHP, 46 octets
Versions en ligne
ou
la source
substr
est inutile (-12 octets). Vous devez mentionner comment les exécuter.-984802906
?<?=bindec(strrev(sprintf("%064b",$argn<<32)));
JS 115
Eh bien, ça n'a pas l'air bien du tout: D
La méthode de @Florian F dans JS est longue de 53 octets:
la source
it may be a function
règle signifie que vous n'avez pas besoin de l'alerte ou de l'inviteC #
8174Les opérations sur les bits qui sont très probablement plus courtes dans tous les langages de programmation.
Fondamentalement, parcourez toutes les puissances de 2 jusqu'au maximum entier + 1 (qui se transforme en une puissance de deux) et depuis (2 147 483 647 + 1) = 0, je peux boucler sur 0. Décalage de bits de gauche à droite pour déplacer le bit dans le premier position. Le dernier bit à la place 32 va 31 pas à droite, l'avant-dernier va 30 etc. Donc, en utilisant l'opérateur AND avec 1, je saurai si c'est 1 ou 0. Si c'est 1, j'ajouterai la valeur i actuelle au résultat et rends le.
la source
i
lorsque vous le déclarez et enregistrer un octet en le supprimanti++
de la boucle for, et au lieu de comparer le résultat de1&...
avec 0, vous pouvez supprimer complètement l'instruction if et multiplieri
par le résultat donnantr|=i*(1&(V>>(31-l++)));
à l'intérieur de la boucleC # 142
Étendu
la source
Python - 37
Similaire à la solution de @ isaacg.
la source
C ++, 160
Ce n'est pas le plus court, mais il n'utilise que 24 opérations.
Tiré du livre Hacker's Delight.
Golfé:
Non golfé:
la source
Haskell, 145 - aucune opération au niveau du bit
Le bit-twiddling me semble être l'antithèse de Haskell, j'ai donc évité toute utilisation d'opérateurs au niveau du bit. Le programme résultant n'est certainement pas le candidat le plus court, mais je pensais que l'utilisation des mathématiques au lieu du bit-twiddling était intéressante au moins.
Explication
0
s et1
s, bit le moins significatif en premier en divisant à plusieurs reprises par 2 et en prenant le reste0
s à la fin de cette liste0
et1
en un entier en supposant que le bit le plus significatif est le premier (répété double et additionné).Je ne sais pas trop ce qui constitue "la bibliothèque standard" dans Haskell, j'ai donc supposé que Data.Tuple et Data.List étaient OK (ils sont assez standard).
En outre, la sortie est un entier 32 bits non signé, car une modification qui me coûterait des octets: je dis cela sous "les omissions sont du jeu gratuit".
la source
PHP,
4641 octetsessayez-les en ligne
au niveau du bit ... plus ou moins. Exécuter en tant que tuyau avec
php -nR '<code>'
.PHP, 46 octets
une solution pure au niveau du bit; courir comme tuyau avec
-nR
.PHP,
4759 octetsune autre approche intégrée; enregistrer dans un fichier et exécuter en tant que pipe avec
-F
.la source
Perl - 60
+1 pour le drapeau p (faites-moi savoir si je compte mal).
Courir avec:
la source
C ++ 69
la source
e;i;
? Les déclarations sans type ne sont pas un C ++ valide. Pour les variables, ce n'est même pas valide C.int r(int n){int e=0,i=0;for(;i<32;)e=e*2|1&n>>i++;return e;}
61 octets :)R, 45
Exemples:
Toujours juste timide des réponses Python. Ce foutu mot-clé de fonction.
la source
Rubis,
4341 octetsdef r(n)(0..31).inject(0){|a,b|a*2+n[b]}end
Dans Ruby, l'utilisation de la notation d'index de parenthèse (foo [i]) renvoie le bit à la nième place.
--Éditer--
La refactorisation de la
inject
fonctionnalité réduit de quelques octetsdef r(n)z=0;32.times{|i|z=z*2+n[i]};z;end
la source
Perl5: 46
Rien d'extraordinaire. Il décale la sortie vers la gauche, copie lsb avant de décaler la source vers la droite.
la source
Clojure,
202156142la source
Perl (37 + 1)
essentiellement un portage de la solution C par Todd Lehman
perl -E '$t=<>;map$r=2*$r|1&$t>>$_,0..31;say$r'
la source