不同数量,相同重量


22

背景

整数的汉明权重是其二进制表示形式中的1的数量。对于此挑战,整数用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之间添加一个奇数,因为某些答案失败了。
与Orjan约翰森


既然您刚刚添加2^31+2,我将重复说一个奇数。在问题的答案只有失败的时候在最高和最低位的1
与Orjan约翰森

我是一个傻瓜。谢谢。将解决该问题
musicman523 '17

1
@ musicman523我刚巧正在浏览活动中的问题,并看到了这个问题。并且注意到您仍然没有添加请求的测试用例。
Draco18s

Answers:


29

x86-64汇编,5 4字节

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

使用C调用约定的函数,将其参数按位左移1位。


该死的-我正好要发布这个-做得好:)
Digital Trauma

12
集会击败果冻:o
Uriel

这不是乘以2吗?如果是这样,那么我的2个字节的Pyth答案可能会获胜
NoOneIsHere17年

@NoOneIsHere没有,这是由2乘以2发送的所需范围之外的输入的一半,如果忽略左侧的溢出位,你已经减1的汉明权重不乘法这是一个按位旋转,使溢出位从右移回。
Anders Kaseorg

1
@DigitalTrauma GCC 4.9.0,后来都足够聪明,编译n << 1 | n >> 31rol的,而不是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)is -1073741825(n=>n>>>31|n<<1)(2147483647)is -2
Anders Kaseorg

2
只要不超过32位就可以了。
musicman523

您可以为第一个添加解释吗?我正在尝试学习Javascript,并且对于如何用k未定义k调用f仍然感到困惑!
musicman523

2
@ musicman523 是相应的技巧。基本上,k最初设置为undefined,我们利用了~undefinedequals 的事实-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

直流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)

更改int为+12个字节long,因为int的最大大小为2³¹-1

通过创建@AndersKaseorg惊人的Python答案端口可以​​节省100 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)

旧答案(117118字节):

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

通过更改int为+1字节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,这有点像高尔夫球的障碍…)


Mod 2 ^ 32-1?(还有4个要去)
user202729 2015年

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字节

(由于@ØrjanJohansen提醒我dup短于push 0,因此节省了1个字节)

   
 
 	
					 
    	 
	 		
	 
   	        
 
 	  
 
 	  
	   
  
   	 
	 	 	
 	

在线尝试!

基本上使用整数算法实现循环右移。在Whitespace中推送大常量非常昂贵,因此我们通过推送2 ^ 8并将其平方两次来节省一些字节。(在(2 ^ 16)^ 2上节省1个字节,在直接推送2 ^ 32上节省10个字节。)

说明

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 0dup一个命令替换第二个命令。
与Orjan约翰森

没错,我刚刚在我的转译器中添加了快捷方式语法,所以我已经使用了太多……
Ephphatha

0

Python 2.7,89个字节

完整程序:

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

在线尝试!

建议欢迎!:)


这是无效的,因为它可能会偶然返回相同的数字。
与Orjan约翰森





By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.