Farklı sayı, aynı ağırlık


22

Arka fon

Hamming ağırlığı bir tamsayı olan ikili gösterimine olanlar sayısıdır. Bu zorluk için, tamsayılar 32 bit ile temsil edilir ve imzasızdırlar.

Meydan okuma

0 ile 2 ^ 32-1 (dahil olmayan) arasında bir tam sayı verildiğinde , aynı aralıkta ve aynı Hamming ağırlığı ile farklı bir tam sayı çıkar.

Örnekler

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)

puanlama

Bu , yani her dilde en az bayttaki çözüm kazanıyor.


2
Bazı cevaplar bunda başarısız olduğu için 2 ^ 31 + 1 ve 2 ^ 32-3 arasına tek bir numara eklemenizi öneririm.
Ørjan Johansen


Yeni eklediğinden beri 2^31+2, garip bir numara söylediğimi tekrarlayacağım . Söz konusu cevaplar sadece hem en yüksek hem de en düşük bit olduğunda başarısız olmuştur 1.
Ørjan Johansen

Ben bir aptalım. Teşekkür ederim. Bunu düzeltecek
musicman523

1
@ musicman523 Sadece aktif sorulara göz atıyordum ve bunu gördüm. Ve istenen sınama durumlarını hala eklemediğinizi fark ettiniz.
Draco18,

Yanıtlar:


29

x86-64 montajı, 5 4 bayt

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

C çağrı kuralını bit yönünde kullanan bir argümanı 1 bit sola döndürür.


Kahretsin - Ben tam olarak bu göndermek üzereydim - aferin :)
Digital Trauma

12
montaj Jelly'i yener: o
Uriel

Bu 2 ile çarpmıyor mu? Öyleyse, 2 bayt Pyth cevabım muhtemelen kazanır
NoOneIsHere

@NoOneIsHere Hayır, bu Bu değil çarpma soldaki taşma biti göz ardı edersek dışında gerekli aralığın girdilerin yarısını ve eğer 1. tarafından Hamming ağırlığı düşürdüyseniz gönderir 2'ye göre 2. Çarpma gereğidir bitdüzeyi taşma bitini sağdan tekrar içeri döndüren döndürme .
Anders Kaseorg

1
@ DigitalTrauma GCC 4.9.0 ve sonrası (bir bayt tasarrufu) yerine derlemek n << 1 | n >> 31için yeterince akıllı . rolror
Anders Kaseorg



6

Jöle , 10 8 bayt

‘&~^^N&$

En az anlamlı olan ve ayarlanmamış bitin yerini alır.

Çevrimiçi deneyin!

Nasıl çalışır

‘&~^^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 bayt

İlk bit geçişini arar (0 → 1 veya 1 → 0) ve onu ters çevirir.

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

gösteri

Bit dönüşü, 14 bayt

Çok daha kısa ama daha az eğlenceli.

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

gösteri


JavaScript bitsel operatörleri, imzasız değil, 32 bit işaretli tamsayılar verir. Örneğin, f(2147483647)bir -1073741825ve (n=>n>>>31|n<<1)(2147483647)bir -2.
Anders Kaseorg

2
32 bitten fazla olmadığı sürece sorun değil.
musicman523

İlki için bir açıklama ekleyebilir misiniz? Javascript'i öğrenmeye çalışıyorum ve k tanımsız ve hala makul bir cevap almaya nasıl f düştüğünüzle ilgili olarak kaybediyorum!
musicman523

2
@ musicman523 İşte karşılık gelen ipucu. Temel olarak, kbaşlangıçta ayarlanır undefinedve ~undefinedeşit olması gerçeğinden yararlanırız -1.
Arnauld

@ musicman523 (Artık bu ipucunu güncellenmiş sürümde kullanmıyorum. Fakat orijinal cevapla ilgili başka sorularınız olup olmadığını sormaktan çekinmeyin.)
Arnauld

4

Brain-Flak , 78 bayt

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

Çevrimiçi deneyin!

N <2 ^ 31, 2n + 1-2 ^ 32 ise 2n döndürür. Ne yazık ki, Brain-Flak bir sayının işaretini belirleme konusunda hızlı bir yolu olmadığından, giriş 2 ^ 31'den 500000'den fazla farklılık gösterirse, program TIO'da zaman aşımına uğrar.

açıklama

İlk önce, yığına -2 ^ 32 basın:

(([()()])[[]()])                               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

Ardından, istenen çıkışı hesaplayın:

      (({}){})                        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

Çevrimiçi deneyin .

Bu bir 32bit sağa döndürme aritmetik uygulamasıdır:

?           # 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 bayt

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

Değiştirerek + 12 bayt intiçin long, çünkü intbireyin maksimum boyutu2³¹-1

@AndersKaseorg'ın şaşırtıcı Python cevabını içeren bir bağlantı noktası oluşturarak 100 89 bayt kaydedildi .

Burada dene.

Çıktılar:

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)

Eski cevap ( 117 118 bayt):

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

Değiştirerek + 1 bayt intiçin long, çünkü intbireyin maksimum boyutu2³¹-1

Burada dene.

Çıktılar:

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 bayt

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

Wolfram sanal alanında deneyin

Aritmetik olarak sola döndürür: önce sayıyı aralık dışına çıkartan sonra 2 ile çarp, daha sonra aralık dışı haneyi kes Mod[...,2^32]ve sonra tekrar sağa ekle +Quotient[...,2^32].

(Mathematica, bir seferde modülü ve katkısı veren tek bir yapıya sahip, ancak QuotientRemainderbiraz, bu bir golf handikapı…)


Mod 2 ^ 32-1? (4 kişi daha)
user202729

2

APL, 12 bayt

(2⊥32⍴1)|2×⊢

Nasıl?

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


1

R, 42 63 bayt

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

Uçları rastgele karıştırır, ancak aynı sayıyı tesadüfen döndürmediğinden emin olmak için kontrol eder.


1

Boşluk , 81 80 bayt

(@ Ørjan Johansen sayesinde kaydedilen 1 bayt, beni tekrar hatırlatmanın 0'dan kısa olduğunu hatırlattı)

   
 
 	
					 
    	 
	 		
	 
   	        
 
 	  
 
 	  
	   
  
   	 
	 	 	
 	

Çevrimiçi deneyin!

Temelde tamsayı aritmetiğini kullanarak bir döngüsel sağ uç kaydırma uygular. Whitespace'de büyük bir sabiti ittirmek pahalıdır, bu yüzden 2 ^ 8 tuşlarına basıp iki kez karelerden bazı baytları kurtarırız. (2 ^ 32'yi doğrudan bastırarak 1 bayttan fazla (2 ^ 16) ^ 2 ve 10 bayttan tasarruf sağlar.)

açıklama

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
Sana ikinci yerini alabilir mi push 0bir ile duptek bir komut daha erken.
Ørjan Johansen

Haklısın, transpilerime kısayol sözdizimi eklemeyi yeni bitirdim, bu yüzden çok fazla kullanıyorum ...
Ephphatha

0

Python 2.7, 89 bayt

Tam Program:

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

Çevrimiçi deneyin!

Önerilerinizi bekliyoruz! :)


Bu geçerli değil çünkü tesadüfen aynı sayıyı tekrar verebilir.
Ørjan Johansen





Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.