Разное количество, тот же вес


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, так как некоторые ответы не дают этого.
Орджан Йохансен,


Поскольку вы только что добавили 2^31+2, я повторю, что сказал нечетное число. Ответы, о которых идет речь, терпят неудачу только тогда, когда имеют место как старший, так и младший биты 1.
Орджан Йохансен

Я дурак. Спасибо.
Исправлю

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
сборка превосходит Jelly: o
Уриэль

Разве это не умножается на 2? Если так, то мой 2-байтовый ответ
Pyth,

@NoOneIsHere Нет, это не умножение на 2. Умножение на 2 отправляет половину входных данных за пределы требуемого диапазона, и если вы игнорируете бит переполнения слева, вы уменьшили вес Хэмминга на 1. Это побитовое вращение , которое возвращает бит переполнения справа назад.
Андерс Касеорг

1
@DigitalTrauma GCC 4.9.0 и более поздние версии достаточно умны для компиляции n << 1 | n >> 31вrol вместо ror(сохранение байта).
Андерс Касеорг



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

Brain-Flak , 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максимальный размер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

Mathematica, 29 байт

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

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

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

(У Mathematica есть единственная встроенная функция, которая дает модуль и частное за один раз, но это QuotientRemainderнемного гандикап для игры в гольф…)


Мод 2 ^ 32-1? (
Осталось

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, напомнившему мне, что dup короче, чем push 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одна командой ранее.
Орджан Йохансен,

Вы правы, я только что закончил добавлять ярлык синтаксиса в свой транспортер, так что я слишком часто его использую ...
Ephphatha






Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.