Різна кількість, однакова вага


22

Фон

Вага Хеммінга цілого числа є число одиниць в його довічним поданні. Для цього виклику цілі числа представлені 32 бітами, і вони не підписані.

Виклик

З огляду на ціле число від 0 до 2 ^ 32-1 (не включаючи), виведіть інше ціле число в межах одного діапазону, а також з однаковою вагою Хеммінга.

Приклади

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)

Оцінка балів

Це , тому рішення в найменших байтах на кожній мові виграє.


2
Я б запропонував додати непарне число між 2 ^ 31 + 1 і 2 ^ 32-3, оскільки деякі відповіді на це не вдається.
Ørjan Johansen


Оскільки ви тільки що додали 2^31+2, я повторю, що я сказав непарне число. Відповіді на запитання не вдалися лише тоді, коли є і найвищий, і найнижчий біт 1.
Ørjan Johansen

Я дурень. Дякую.
Виправимо

1
@ musicman523 Щойно я переглядав активні запитання і бачив це. І помітили, що ви досі не додали запитувані тестові випадки.
Draco18s

Відповіді:


29

x86-64 збірка, 5 4 байти

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

Функція, що використовує конвенцію виклику C, яка побіжно обертає свій аргумент, залишений на 1 біт.


Чорт - я збирався розмістити саме це - молодець :)
Digital Trauma

12
збірка б'є Желе: o
Уріель

Хіба це не множення на 2? Якщо так, то моя 2-байтна відповідь Pyth, ймовірно, перемагає
NoOneIsHere

@NoOneIsHere Ні, це не множення на 2. Множення на 2 посилає половину входів за межами необхідного діапазону, і якщо ви ігноруєте біт переповнення зліва, ви зменшили вагу Хеммінга на 1. Це побіжно обертання , яке повертає біт переливу праворуч.
Андерс Касеорг

1
@DigitalTrauma GCC 4.9.0 і пізніші версії досить розумні, щоб компілювати n << 1 | n >> 31їх rolзамість ror(збереження байта).
Anders Kaseorg



6

Желе , 10 8 байт

‘&~^^N&$

Заміняє найменш значущий набір і скинутий біт.

Спробуйте в Інтернеті!

Як це працює

‘&~^^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 байт

Шукає перший бітовий перехід (0 → 1 або 1 → 0) та інвертує його.

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

Демо

Обертання біт, 14 байт

Набагато коротше, але менш весело.

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

Демо


Бітові оператори JavaScript дають 32-бітні цілі числа, а не непідписані. Наприклад, f(2147483647)є -1073741825і (n=>n>>>31|n<<1)(2147483647)є -2.
Андерс Касеорг

2
Це добре, якщо не більше 32 біт.
musicman523

Чи можете ви додати пояснення до першого? Я намагаюсь вивчити Javascript, і я певний збиток щодо того, як ви викликаєте f з k undefined та все ще отримуєте розумну відповідь!
musicman523

2
@ musicman523 Ось відповідна порада. В основному, kспочатку встановлено, undefinedі ми скористаємося тим, що ~undefinedдорівнює -1.
Арнольд

@ musicman523 (Я вже не використовую цю пораду в оновленій версії. Але не соромтеся запитати, чи є у вас інші запитання щодо оригінальної відповіді.)
Арнольд,

4

Мозок-Флак , 78 байт

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

Спробуйте в Інтернеті!

Повертає 2n, якщо n <2 ^ 31, а 2n + 1-2 ^ 32 в іншому випадку. На жаль, оскільки у Brain-Flak немає жодного швидкого способу визначення знаку числа, програма вимкнеться на TIO, якщо вхід відрізняється від 2 ^ 31 більш ніж на 500000.

Пояснення

Спочатку натисніть -2 ^ 32 на стек:

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

Потім обчисліть потрібний вихід:

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

постійний струм, 10

?2~z31^*+p

Спробуйте в Інтернеті .

Це арифметична реалізація 32-бітового правого повороту:

?           # 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 байт

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

+12 байт, змінивши intна long, тому intщо розмір max є2³¹-1

Збережено 100 89 байт, створивши порт дивовижної відповіді Python @AndersKaseorg .

Спробуйте тут.

Виходи:

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)

Стара відповідь ( 117 118 байт):

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

+1 байт, змінивши intна long, тому intщо максимальний розмір є2³¹-1

Спробуйте тут.

Виходи:

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

Математика, 29 байт

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

Спробуйте це в пісочниці Wolfram

Обертається лівоарифметично: спочатку помножте на 2, що можливо зміщує число поза діапазоном, потім відріжте цифру поза діапазоном Mod[...,2^32]і додайте її назад праворуч за допомогою +Quotient[...,2^32].

(У Mathematica є єдиний вбудований модуль, який дає модуль та коефіцієнт за один раз, але це QuotientRemainder, що є дещо гандикапом для гольфу…)


Мод 2 ^ 32-1? (Ще 4)
користувач202729

2

APL, 12 байт

(2⊥32⍴1)|2×⊢

Як?

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


1

R, 42 63 байти

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

Перемішує шматочки навмання, але перевіряє, чи випадково не повернуло те саме число.


1

Пробіл , 81 80 байт

(1 байт збережено завдяки @ Ørjan Johansen, який нагадує мені, що дубль коротший, ніж натиснути 0)

   
 
 	
					 
    	 
	 		
	 
   	        
 
 	  
 
 	  
	   
  
   	 
	 	 	
 	

Спробуйте в Інтернеті!

В основному реалізує циклічне право бітового зсуву, використовуючи цілу арифметику. Натискання великої константи дорого коштує в Whitespace, тому ми економимо кілька байтів, натискаючи 2 ^ 8 і квадратикуючи їх двічі. (Економія на 1 байт (2 ^ 16) ^ 2 та 10 байт на натисканні 2 ^ 32 безпосередньо.)

Пояснення

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
Я думаю, ви можете замінити другу push 0на dupодну команду раніше.
Ørjan Johansen

Ви маєте рацію, я щойно закінчив додавати синтаксис ярликів до мого транспілера, тому я занадто багато його використовую ...
Ephphatha






Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.