加倍,异或再做一次


20

对于任何大于0的整数,我们将函数g定义为g(n)= n XOR(n * 2)

给定x> 0,找到最小整数y> 0,使得对于某些k> 0g k(y)= x

x = 549

549 = 483 XOR (483 * 2)     (as binary: 1000100101 = 111100011 XOR 1111000110)
483 = 161 XOR (161 * 2)     (as binary:  111100011 =  10100001 XOR  101000010)

这意味着g 2(161)= 549。我们不能再走了,因为没有n使得g(n)= 161。因此,对于期望的输出X = 549Y = 161

规则

  • 您不应该支持无效的条目。对于输入值x,保证存在一对(y,k)
  • 这是,因此最短答案以字节为单位!

测试用例

     3 -->     1
     5 -->     1
     6 -->     2
     9 -->     7
    10 -->     2
    23 -->    13
    85 -->     1
   549 -->   161
   960 -->    64
  1023 -->   341
  1155 -->   213
  1542 -->     2
  9999 -->  2819
 57308 --> 19124
 57311 -->   223
983055 -->     1

3
相关的OEIS:A048274,即序列a(n) = g(n)
Giuseppe

Answers:


5

Java 8,68 57 53 52字节

n->{for(int i=0;i<n;)i-=(i*2^i)==n?n=i:-1;return n;}

-5个字节,感谢@OlivierGrégoire

在线尝试。

说明:

n->{                 // Method with integer as both parameter and return-type
  for(int i=0;i<n;)  //  Loop `i` in the range (1,n)
    i-=(i*2^i)==n?   //   If `i*2` XOR-ed with `i` equals `n`
        n=i          //    Set `n` to `i`, and set `i` to 0 to reset the loop
       :             //   Else:
        -1;          //    Increase `i` by 1 to go to the next iteration
  return n;}         //  Return `n` after the entire loop

1
n->{for(int i=0;i<n;)i-=(i*2^i)==n?n=i:-1;return n;}(52个字节)。抱歉^^'
OlivierGrégoire18年

@OlivierGrégoire更聪明,谢谢!
凯文·克鲁伊森

for(int i=0;n>i-=i+i^i^n?-1:n=i;);
泰特斯

@Titus恐怕在Java中不起作用(尽管我在迭代JavaScript答案中使用了该方法)。在Java i+i^i^n?中不是布尔值,因此它甚至都不会编译。另外,n>i-=...将需要括号(n>(i-=...)),并且n=i在三进制if的else子句中是不允许的,仅在if子句中是不允许的(这最后一个我不知道为什么,但是不幸的是,这就是Java中的含义) )。
凯文·克鲁伊森

1
@KevinCruijssen“并且n=i在三进制if的else子句中是不允许的”。因为Java会将其解析(i-=(i*2^i)!=n?-1:n)=i为非法。
奥利维尔·格雷戈尔


3

JavaScript,53个字节

f=x=>(i=0,y=(G=x=>x&&(i^=x&1)+2*G(x>>1))(x),i?x:f(y))

Gg^-1,其设置i0,如果成功,将i1,如果失败。


1
这是我试图用我虽然想出了一个50字节版本的方法:f=n=>(g=n=>n<2?0/!n:n%2+2*g(n/2^n%2))(n)?f(g(n)):n。可悲的是,无聊的方法要短12个字节。
尼尔

3

Pyth13 12 10字节

@MrXcoder节省了1个字节,在他们的建议之后又节省了2个字节

fqQ.W<HQxy

在线尝试

说明:

fqQ.W<HQxyZZT   Implicit: Q=eval(input()), trailing ZZT inferred

f               Return the first T in [1,2,3...] where the following is truthy
   .W       T     Functional while - loop until condition is true, starting value T
     <HQ            Condition: continue while iteration value (H) less than input
        xyZZ        Body: xor iteration value (Z) with double (y) iteration value (Z)
 qQ               Is the result of the above equal to input?

1
您可以删除结尾T的12个字节。
Xcoder先生

3

R73 65字节

f=function(x){for(i in 1:x)if(x==bitwXor(i,i*2)){i=f(i);break};i}

在线尝试!

非常感谢Giuseppe(-8)的调整,如此简单却非常有效


1
与您先前的答案相反,由于此函数是递归的,因此您确实需要使用,f=因为该函数需要绑定f才能正常工作。话虽如此,辛苦了,从我这里+1!
朱塞佩

2
您还可以对逻辑进行一些重新调整,并将其保留为65个字节
Giuseppe

2

JavaScript,38 36字节

f=(n,x=n)=>x?x^x+x^n?f(n,--x):f(x):n

在线尝试 -开始在9999&之间抛出溢出错误57308



2

C(gcc)57 56 55 51字节

  • 多亏了ceilingcat,节省了一个字节;!=〜  -
  • 多亏Rogem节省了一个字节 5个字节; 利用三元表达式和gcc怪癖。
X(O,R){for(R=1;R;O=R?R:O)for(R=O;--R&&(R^2*R)-O;);}

在线尝试!


1
+1X(O,R)
JayCe

@ceilingcat很好的建议,谢谢。
Jonathan Frech

for(R=1;R;O=R?R:O)保存一个字节。

R=O;最后似乎没有必要,可以再节省4个字节。

@Rogem似乎是,谢谢。
乔纳森·弗雷希

2

Z80高尔夫球,22字节

00000000: 1600 1803 4216 007a b830 097a 82aa b828  ....B..z.0.z...(
00000010: f314 18f3 78c9                           ....x.

@KevinCruijssen的Java答案端口

输入9的示例-在线尝试!

输入85的示例-在线尝试!

部件:

;d=loop counter
;b=input and output
f:
	ld d,0
	jr loop
	begin:
	ld b,d
	ld d,0
	loop:
		ld a,d
		cp b
		jr nc,end	; if d==b end
		ld a,d
		add d		; mul by 2
		xor d
		cp b
		jr z,begin	; if (d*2)^d==b set b to d
		inc d
		jr loop
	end:
	ld a,b
	ret

调用函数并打印结果的汇编示例:

ld b,9 ; input to the function, in this case 9
call f
add 30h ; ASCII char '0'
call 8000h ; putchar
halt

如果使用a而不是使用循环计数器d,则可以两次替换ld d,0指令xor a,这样可以节省两个字节。
米沙·拉夫罗夫


1

JavaScript(Node.js),48 45 38字节

f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n

-7个字节,感谢@Neil在下面创建了我的迭代版本的递归版本。对于大型测试用例不起作用。

在线尝试。


45字节迭代版本,适用于所有测试用例:

n=>{for(i=0;i<n;)i-=i*2^i^n?-1:n=i;return n;}

我的Java回答的端口。
-3个字节,感谢@Arnauld

在线尝试。


1
您可以做到i-=i*2^i^n?-1:n=i(但不幸的是,不是在Java中)。
Arnauld

@Arnauld认为Java中的布尔值仅适用1于JS中的某种可能性。谢谢!
凯文·克鲁伊森

1
递归写入38个字节(不适用于较大的输入):f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n
Neil

1

Ruby,39个字节

f=->x,y=x{y<1?x:x==y^y*2?f[y]:f[x,y-1]}

在线尝试!

正如递归版本所期望的那样,后者的测试用例抱怨“堆栈级别太深”。


1

果冻11 9字节

BÄḂṛḄß$Ṫ?

在线尝试!

提示:使用递归函数而不是循环。


很快,不幸的是失去了暴力手段。

注意:

  • 对于x> 0f(x)> x
  • popcount(f(x))是偶数,其中popcount(n)是在n中设置的位数
  • 如果n的偶数为偶数,则存在x使得 f(x)= n
  • B(x)的是的二进制表示X,和P(L)是该列表移除最后一个元素。那么B(x)Ṗ(B(f(x)))的累加XOR 。

因此,我们反复:

  • 计算其二进制表示形式(B
  • 然后进行累加的XOR(使用^\ÄḂ,它们具有相同的效果)。
  • 检查(?累加XOR 的尾部(最后一个元素)()是否为非零(奇数弹出计数)
    • 如果是这样,将二进制列表转换回十进制并递归。
    • 如果不是,则返回输入()。

9个字节:B^\⁸Ḅß$Ṫ?
Leaky Nun

1

第四(gforth),71字节

: f 0 begin 2dup dup 2* xor = if nip 0 else 1+ then 2dup < until drop ;

在线尝试!

说明

0                 \ add an index variable to the top of the stack
begin             \ start an indefinite loop
  2dup            \ duplicate the top two stack items (n and i)
  dup 2* xor =    \ calculate i xor 2i and check if equal to n
  if nip 0        \ if equal, drop n (making i the new n) and use 0 as the new i
  else 1+         \ otherwise just increment i by 1
  then            \ end the if-statement
  2dup <          \ duplicate the top two stack items and check if n < i
until             \ if previous statement is true, end the loop
drop              \ drop i, leaving n on top of the stack

1

Perl 6,44个字节

{({first {($^a+^2*$a)==$_},^$_}...^!*).tail}

试试吧

展开:

{  # bare block lambda with implicit parameter $_

  (
    # generate a sequence

    # no need to seed the sequence with $_, as the following block will
    # default to using the outer $_
    # $_, 

    { # parameter $_

      first
        {  # block with placeholder parameter $a

          ( $^a +^ 2 * $a ) # double (numeric) xor
          == $_             # is it equal to the previous value
        },

        ^$_  # Range up to and excluding the previous value ( 0..^$_ )
    }

    ...^  # keep doing that until: (and throw away last value)

    !*    # it doesn't return a trueish value

  ).tail  # return the last generated value
}


1

PHP,49字节

基于Kevin Cruijssen的答案。

for($x=$argn;$x>$i-=$i*2^$i^$x?-1:$x=$i;);echo$x;

与管道一起运行-nr在线尝试


1

F#,92个字节

let rec o i=
 let r=Seq.tryFind(fun x->x^^^x*2=i){1..i-1}
 if r.IsNone then i else o r.Value

在线尝试!

递归地检查从1到的数字i-1。如果有匹配项,请检查该数字是否较小。如果不匹配,则返回输入数字。


1

JavaScript(Node.js),40字节

f=n=>g(n)%2?n:f(g(n)/2)
g=x=>x&&x^g(x/2)

在线尝试!

感谢Shaggy -1个字节。

果冻港口的答案

最后是一种语言,这种方法更短哎呀)。(我尝试使用Python和Java,但无法使用)

谁能解释为什么我可以/2代替使用>>1


1
x/2由于算术下溢而起作用。如果将IEEE 754数除以2,则最终将被评估为0。(XOR运算后,小数部分将被忽略,因此不会影响结果。)
Arnauld


@Shaggy惊讶于它的工作原理。我知道它适用于Python和Lua等,但不适用于Javascript。
user202729

按位XOR运算符false隐式将最后一次迭代的返回值强制转换0为。
粗野的

@Shaggy实际上false涉及。JS的&&行为几乎与Python / Lua相同and
user202729

1

K(ngn / k)32 26字节

{$[*|a:2!+\2\x;x;2/-1_a]}/

在线尝试!

{ } 是带有参数的函数 x

/ 应用它直到收敛

$[ ; ; ] 如果-然后-其他

2\x 的二进制数 x(特定于ngn / k)

+\ 部分和

2! Mod 2

a: 分配给 a

*|最后-反转(|)并获得第一个(*

如果以上为1, x将返回

除此以外:

-1_a 删除的最后一个元素 a

2/ 解码二进制


0

C,62字节

基于Kevin Cruijssen的Java:

int n(int j){for(int i=0;i<j;)i-=(i*2^i)==j?j=i:-1;return j;}

去测试:

#include <stdio.h>
int n(int j);
#define p(i) printf("%6d --> %5d\n", i, n(i))
int main(void)
{
    p(3);
    p(5);
    p(6);
    p(9);
    p(10);
    p(23);
    p(85);
    p(549);
    p(960);
    p(1023);
    p(1155);
    p(1542);
    p(9999);
    p(57308);
    p(57311);
    p(983055);
}

运行时,测试程序输出:

     3 -->     1
     5 -->     1
     6 -->     2
     9 -->     7
    10 -->     2
    23 -->    13
    85 -->     1
   549 -->   161
   960 -->    64
  1023 -->   341
  1155 -->   213
  1542 -->     2
  9999 -->  2819
 57308 --> 19124
 57311 -->   223
983055 -->     1

C,54个字节

仅适用于C89或K&R C:

n(j){for(i=0;i<j;)i-=(i*2^i)==j?j=i:-1;return j;}


int n(int j){for(int i=0;j>i-=i*2^i^j?-1:j=i;);return j;}这57个字节有效吗?
泰特斯

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.