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.


2
Je suggère d'ajouter un nombre impair entre 2 ^ 31 + 1 et 2 ^ 32-3, car certaines réponses échouent.
Ørjan Johansen


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.


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.



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.

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


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

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

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)

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…)


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


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.


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

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! :)


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





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.