Numéro différent, même poids

22

Contexte

Le poids de Hamming d'un entier est le nombre d'unités dans sa représentation binaire. Pour ce défi, les entiers sont représentés avec 32 bits et ils ne sont pas signés.

Défi

Étant donné un entier compris entre 0 et 2 ^ 32-1 (non inclus), sortez un entier différent dans la même plage, et également avec le même poids de Hamming.

Exemples

Input (Decimal) | Input (Binary) | Hamming weight | Possible output (Decimal)
       46       |   0b0010 1110  |       4        |      15
       12       |   0b0000 1100  |       2        |      3
        1       |   0b0000 0001  |       1        |      2
        3       |   0b0000 0011  |       2        |      6
      2^31      |   0b1000....0  |       1        |      1
      2^31+2    |   0b1000...10  |       2        |      3
      2^32-5    |   0b1111..011  |       31       |      2^31-1
      2^32-2    |   0b1111....0  |       31       |      2^31-1
        0       |   0b0000 0000  |       0        | None (This case need not be handled)
      2^32-1    |   0b1111....1  |       32       | None (This case need not be handled)

Notation

C'est du , donc la solution dans le moins d'octets dans chaque langue l'emporte.

musicman523
la source
2
Je suggère d'ajouter un nombre impair entre 2 ^ 31 + 1 et 2 ^ 32-3, car certaines réponses échouent.
Ørjan Johansen
En relation.
Martin Ender
Puisque vous venez d'ajouter 2^31+2, je répète que j'ai dit un nombre impair . Les réponses en question seulement échoué lorsque les deux le plus haut et le bit le plus bas sont 1.
Ørjan Johansen
Je suis un imbécile. Merci.
Résoudra
1
@ musicman523 Je viens de parcourir des questions actives et j'ai vu celle-ci. Et vous avez remarqué que vous n'avez toujours pas ajouté les cas de test demandés.
Draco18s

Réponses:

29

assemblage x86-64, 5 4 octets

   0:   97                      xchg   %eax,%edi
   1:   d1 c0                   rol    %eax
   3:   c3                      retq   

Une fonction utilisant la convention d'appel C qui tourne au niveau du bit son argument de 1 bit vers la gauche.

Anders Kaseorg
la source
Bon sang - j'étais sur le point de poster exactement ceci - bravo :)
Digital Trauma
12
l'assemblée bat Jelly: o
Uriel
N'est-ce pas multiplier par 2? Si oui, alors ma réponse Pyth à 2 octets l'emporte probablement
NoOneIsHere
@NoOneIsHere Non, ce n'est pas une multiplication par 2. La multiplication par 2 envoie la moitié des entrées en dehors de la plage requise, et si vous ignorez le bit de débordement à gauche, vous avez diminué le poids de Hamming de 1. C'est un bit à bit rotation , ce qui ramène le bit de débordement de la droite.
Anders Kaseorg
1
@DigitalTrauma GCC 4.9.0 et versions ultérieures sont suffisamment intelligents pour être compilés n << 1 | n >> 31au rollieu de ror(enregistrer un octet).
Anders Kaseorg
8

Python, 20 octets

lambda x:x*2%~-2**32

Rotation au niveau du bit à gauche de 1 bit.

Anders Kaseorg
la source
6

Gelée , 10 8 octets

‘&~^^N&$

Échange le bit le moins significatif défini et non défini.

Essayez-le en ligne!

Comment ça marche

‘&~^^N&$  Main link. Argument: n

‘         Increment; yield n+1, toggling all trailing set bits and the rightmost
          unset bit.
  ~       Bitwise NOT; yield ~n, toggling ALL bits of n.
 &        Bitwise AND; yield (n+1)&~n, keeping the only bit that differs in n+1 and
          ~n, i.e., the rightmost unset bit.
   ^      Perform bitwise XOR with n, toggling the rightmost unset bit.
       $  Combine the two links to the left into a monadic chain.
     N        Negate; yield -n. Since ~n = -(n+1) in 2's complement, -n = ~n+1.
      &       Take the bitwise AND of n and -n. Since -n = ~n + 1 and n = ~~n, the
              same reasoning that applied for (n+1)&~n applies to -n&n; it yields
              the rightmost unset bit of ~n, i.e., the rightmost set bit of n.
    ^      XOR the result to the left with the result to the right, toggling the
           rightmost set bit of the left one.
Dennis
la source
5

JavaScript (ES6), 35 31 octets

Recherche la première transition de bit (0 → 1 ou 1 → 0) et l'inverse.

f=(n,k=3)=>(n&k)%k?n^k:f(n,k*2)

Démo

Rotation des bits, 14 octets

Beaucoup plus court mais moins amusant.

n=>n>>>31|n<<1

Démo

Arnauld
la source
Les opérateurs JavaScript au niveau du bit donnent des entiers signés 32 bits plutôt que non signés. Par exemple, f(2147483647)est -1073741825et (n=>n>>>31|n<<1)(2147483647)est -2.
Anders Kaseorg
2
C'est bien tant qu'il n'y a pas plus de 32 bits.
musicman523
Pouvez-vous ajouter une explication pour la première? J'essaie d'apprendre Javascript, et je ne sais pas comment vous appelez f avec k non défini et obtenez toujours une réponse raisonnable!
musicman523
2
@ musicman523 Voici l'astuce correspondante. Fondamentalement, kest initialement défini sur undefinedet nous profitons du fait que ~undefinedégal -1.
Arnauld
@ musicman523 (Je n'utilise plus cette astuce dans la version mise à jour. Mais n'hésitez pas à demander si vous avez d'autres questions sur la réponse originale.)
Arnauld
4

Brain-Flak , 78 octets

(([()()])[[]()]){((){}<({({})({}())}{})>)}{}([(({}(({}){})())<>)]){({}())<>}{}

Essayez-le en ligne!

Renvoie 2n si n <2 ^ 31 et 2n + 1-2 ^ 32 sinon. Malheureusement, parce que Brain-Flak n'a aucun moyen rapide de déterminer le signe d'un nombre, le programme expire sur TIO si l'entrée diffère de 2 ^ 31 de plus d'environ 500000.

Explication

Tout d'abord, poussez -2 ^ 32 sur la pile:

(([()()])[[]()])                               push (initial value) -2 and (iterator) -5
                {((){}<                >)}     do 5 times:
                       ({({})({}())}{})        replace the current (negative) value with the negation of its square
                                            {}   pop the (now zero) iterator

Ensuite, calculez la sortie souhaitée:

      (({}){})                        replace n by 2n on left stack
   ({}        ())                     push 2n+1-2^32 on left stack
  (              <>)                  push again on right stack
([                  ])                push its negation on right stack
                      {({}())<>}      add 1 to the top value of each stack until one of them reaches zero
                                {}    pop this zero, and implicitly print the number below it on the stack
Nitrodon
la source
3

dc, 10

?2~z31^*+p

Essayez-le en ligne .

Il s'agit d'une implémentation arithmétique d'une rotation à droite de 32 bits:

?           # input
 2~         # divmod by 2 - quotient pushed first, then the remainder
   z        # z pushes the size of the stack which will be 2 (quotient and remainder) ...
    31^     #  ... and take that 2 to the 31st power
       *    # multiply the remainder by 2^31
        +   # add
         p  # output
Traumatisme numérique
la source
3

Java 8, 117 17 29 octets

n->n*2%~-(long)Math.pow(2,32)

+12 octets en passant intà long, car intla taille maximale de2³¹-1

100 89 octets enregistrés en créant un port de la réponse Python étonnante de @AndersKaseorg .

Essayez-le ici.

Les sorties:

46 (101110):                                     92 (1011100)
12 (1100):                                       24 (11000)
1 (1):                                           2 (10)
3 (11):                                          6 (110)
10000 (10011100010000):                          20000 (100111000100000)
987654 (11110001001000000110):                   1975308 (111100010010000001100)
2147483648 (10000000000000000000000000000000):   1 (1)
4294967294 (11111111111111111111111111111110):   4294967293 (11111111111111111111111111111101)

Ancienne réponse ( 117 118 octets):

n->{long r=0;for(;!n.toBinaryString(++r).replace("0","").equals(n.toBinaryString(n).replace("0",""))|r==n;);return r;}

+1 octet en changeant inten long, car intla taille maximale de2³¹-1

Essayez-le ici.

Les sorties:

46 (101110):                                     15 (1111)
12 (1100):                                       3 (11)
1 (1):                                           2 (10)
3 (11):                                          5 (101)
10000 (10011100010000):                          31 (11111)
987654 (11110001001000000110):                   255 (11111111)
2147483648 (10000000000000000000000000000000):   1 (1)
Kevin Cruijssen
la source
2

Mathematica, 29 octets

Mod@##+Quotient@##&[2#,2^32]&

Essayez-le au bac à sable Wolfram

Rotation arithmétique vers la gauche: multipliez d'abord par 2, ce qui peut éventuellement déplacer le nombre hors de la plage, puis coupez le chiffre hors de la plage avec Mod[...,2^32]et ajoutez-le à droite avec +Quotient[...,2^32].

(Mathematica a un seul module intégré qui donne le module et le quotient en une seule fois, mais ça l'est QuotientRemainder, ce qui est un peu un handicap au golf…)

Pas un arbre
la source
Mod 2 ^ 32-1? (4 de plus à parcourir)
user202729
2

APL, 12 octets

(2⊥32⍴1)|2×⊢

Comment?

           ⊢  ⍝ monadic argument
         2×   ⍝ shift left (×2)
(2⊥32⍴1)|     ⍝ modulo 2^32 - 1
Uriel
la source
1

R, 42 63 octets

function(x){s=x;while(s==x){sample(binaryLogic::as.binary(x))}}

Mélange les bits au hasard, mais vérifie qu'il ne retourne pas le même nombre par hasard.

BLT
la source
1

Espace , 81 80 octets

(1 octet sauvé grâce à @ Ørjan Johansen me rappelant que dup est plus court que push 0)

   
 
 	
					 
    	 
	 		
	 
   	        
 
 	  
 
 	  
	   
  
   	 
	 	 	
 	

Essayez-le en ligne!

Implémente fondamentalement un décalage cyclique vers la droite en utilisant l'arithmétique entière. Pousser une grande constante coûte cher dans l'espace blanc, donc nous économisons quelques octets en poussant 2 ^ 8 et en la quadrillant deux fois. (Enregistre 1 octet de plus (2 ^ 16) ^ 2 et 10 octets de plus en poussant directement 2 ^ 32.)

Explication

sssn  ; push 0
sns   ; dup
tntt  ; getnum from stdio
ttt   ; retrieve n from heap and put it on the stack
sns   ; dup
ssstsn ; push 2
tstt  ; mod - check if divisible by 2 (i.e. even)
ntsn  ; jez "even"
ssstssssssssn ; push 2^8
sns   ; dup
tssn  ; mul - square it to get 2^16
sns   ; dup
tssn  ; mul - square it to get 2^32
tsss  ; add 2^32 so MSB ends up set after the divide
nssn  ; even:
ssstsn ; push 2
tsts  ; divide by 2, aka shift right
tnst  ; putnum - display result
Ephphatha
la source
1
Je pense que vous pouvez remplacer le second push 0par une dupcommande plus tôt.
Ørjan Johansen
Vous avez raison, je viens de terminer d'ajouter la syntaxe de raccourci à mon transpilateur, donc je l'utilise trop ...
Ephphatha
0

Python 2.7, 89 octets

Programme complet:

from random import*;a=list(bin(input())[2:].zfill(32));shuffle(a);print int(''.join(a),2)

Essayez-le en ligne!

Bienvenue suggestions! :)

Koishore Roy
la source
Ce n'est pas valable car il peut par hasard renvoyer le même numéro.
Ørjan Johansen
0

Japt , 5 octets

Ñ%3pH

Rotation au niveau du bit, comme la plupart des réponses ici.

Essayez-le

Incarnation de l'ignorance
la source