다른 숫자, 같은 무게


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 2016 년

나는 바보다. 고맙습니다. 그것을 해결할 것입니다
— musicman523

1
@ musicman523 방금 활발한 질문을 탐색 하면서이 질문을 보았습니다. 요청한 테스트 사례를 아직 추가하지 않은 것으로 나타났습니다.
— Draco18s

답변:


29

x86-64 어셈블리, 5 4 바이트

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

C 호출 규칙을 사용하여 인수를 1 비트 씩 왼쪽으로 회전시키는 함수입니다.


젠장 - 내가 게시물에 대해 정확히 동일하게이 - 잘 :) 일
— 디지털 외상

12
어셈블리는 Jelly : o
— Uriel

이 값에 2를 곱하지 않습니까? 만약 그렇다면, 제 2 바이트 Pyth의 대답은 아마도 승리
— NoOneIsHere

@NoOneIsHere 아니, 이것은 이것은하지 곱셈 왼쪽의 오버 플로우 비트를 무시하면 외부 필요한 범위의 입력의 절반, 그리고 당신이 1만큼 해밍 무게를 감소했습니다 보냅니다 2 2. 곱셈입니다 비트 rotation . 오버플로 비트를 오른쪽에서 다시 가져옵니다.
— Anders Kaseorg 2012 년

1
@DigitalTrauma GCC 4.9.0 및 이후 버전은 컴파일 할만큼 똑똑 n << 1 | n >> 31로 rol대신 ror(바이트 저장).
— Anders Kaseorg 2012 년



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

자바 스크립트 (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)is -1073741825and (n=>n>>>31|n<<1)(2147483647)is -2입니다.
— Anders Kaseorg 2016 년

2
32 비트를 넘지 않는 한 괜찮습니다.
— musicman523 2016 년

첫 번째 설명을 추가 할 수 있습니까? Javascript를 배우려고하는데 k가 정의되지 않은 상태에서 f를 호출하고 합리적인 대답을 얻는 방법에 대해 약간의 손실이 있습니다!
— musicman523

2
@ musicman523 다음 은 해당 팁입니다. 기본적 k으로는로 설정되어 있으며이 undefined사실을 이용합니다 . ~undefined-1
— Arnauld

@ musicman523 (업데이트 된 버전에서는이 팁을 더 이상 사용하지 않습니다. 그러나 원래 답변에 대해 다른 질문이 있으면 언제든지 문의하십시오.)
— Arnauld

4

Brain-Flak , 78 바이트

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

온라인으로 사용해보십시오!

n <2 ^ 31이면 2n을, 그렇지 않으면 2n + 1-2 ^ 32를 반환합니다. 불행히도, Brain-Flak은 숫자의 부호를 결정하는 빠른 방법이 없기 때문에 입력 값이 2 ^ 31과 약 500000 이상 차이가 나면 프로그램이 TIO에서 시간 초과됩니다.

설명

먼저 -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

dc, 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

자바 8, 117 17 29 바이트

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

의 최대 크기가 이므로 으로 변경 int하여 +12 바이트longint2³¹-1

100@AndersKaseorg 의 놀라운 파이썬 답변 포트를 생성하여 89 바이트 절약 .

여기에서 시도하십시오.

출력 :

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 바이트) :

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

변경하여 +1 바이트 int의 최대 크기가 long이므로 하여int2³¹-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 더 이동)
— user202729

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 바이트

(@ Ørjan Johansen 덕분에 1 바이트가 절약되어 dup이 푸시 0보다 짧다는 것을 상기시킵니다)

   
 
 	
					 
    	 
	 		
	 
   	        
 
 	  
 
 	  
	   
  
   	 
	 	 	
 	

온라인으로 사용해보십시오!

기본적으로 정수 산술을 사용하여 순환 오른쪽 비트 시프트를 구현합니다. 공백에서 큰 상수를 푸는 것은 비싸므로 2 ^ 8을 누르고 두 번 제곱하여 일부 바이트를 절약합니다. (1 ^ 2 바이트 이상 (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 0A를 dup하나의 명령 이전을.
— Ørjan Johansen 2016 년

당신의 말이 맞아요, 방금 트랜스포머에 바로 가기 구문을 추가해서 너무 많이 사용했습니다 ...
— Ephphatha






당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.