เพิ่มเป็นสองเท่า XOR และทำอีกครั้ง


20

เรากำหนดฟังก์ชั่นกรัมเป็นกรัม (n) = n แฮคเกอร์ (n * 2)สำหรับจำนวนเต็มใด ๆn> 0

รับx> 0หาจำนวนเต็มที่น้อยที่สุดy> 0ซึ่งg k (y) = xสำหรับk> 0บางตัว

ตัวอย่าง

x = 549

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

ซึ่งหมายความว่าก. 2 (161) = 549 เราไม่สามารถไปเพิ่มเติมใด ๆ เพราะไม่มีnดังกล่าวว่ากรัม (n) = 161 ดังนั้นการส่งออกคาดว่าx = 549คือการ y = 161

กฎระเบียบ

  • คุณไม่ควรสนับสนุนรายการที่ไม่ถูกต้อง คู่(y, k)รับประกันได้ว่าจะมีอยู่สำหรับค่าอินพุตx
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ!

กรณีทดสอบ

     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

คำตอบ:


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égoireยิ่งฉลาดยิ่งขึ้นขอบคุณ!
Kevin Cruijssen

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ไม่ได้รับอนุญาตใน else-clause ของ ternary-if เฉพาะใน if-clause (อันสุดท้ายนี้ฉันไม่รู้ว่าทำไม แต่นั่นคือสิ่งที่อยู่ใน Java อย่างน่าเสียดาย )
Kevin Cruijssen

1
@KevinCruijssen "และn=iไม่อนุญาตให้ใช้ในส่วนอื่นของคำศัพท์แบบไตรภาค - if" เพราะจาวาจะแยกวิเคราะห์ตาม(i-=(i*2^i)!=n?-1:n)=iที่ผิดกฎหมาย
Olivier Grégoire


3

JavaScript ขนาด 53 ไบต์

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

Gคือg^-1ซึ่งตั้งค่าiเป็น0หากสำเร็จตั้งค่าiเป็น1หากล้มเหลว


1
นี่คือวิธีการที่ผมพยายามที่จะใช้แม้ว่าฉันมากับรุ่น 50 f=n=>(g=n=>n<2?0/!n:n%2+2*g(n/2^n%2))(n)?f(g(n)):nไบต์: น่าเศร้าที่วิธีการที่น่าเบื่อนั้นสั้นกว่า 12 ไบต์
Neil

3

Pyth , 13 12 10 ไบต์

บันทึกแล้ว 1 ไบต์ขอบคุณ @MrXcoder และอีก 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
คุณสามารถวางส่วนท้ายได้T12 ไบต์
นาย Xcoder

3

R , 73 65 ไบต์

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

ลองออนไลน์!

ขอบคุณมากจูเซปเป้ (-8) เนื่องจากการปรับแต่งของคุณง่ายมาก แต่มีประสิทธิภาพมาก


1
เมื่อเทียบกับคำตอบก่อนหน้าของคุณเพราะฟังก์ชั่นนี้เป็น recursive คุณไม่จำเป็นต้องมีf=ตั้งแต่ความต้องการฟังก์ชั่นที่จะผูกพันที่จะfทำงานอย่างถูกต้อง ที่ถูกกล่าวว่าเป็นงานที่ดีและใช้ +1 จากฉัน!
Giuseppe

2
นอกจากนี้คุณยังสามารถสร้างตรรกะของคุณขึ้นมาใหม่เพื่อให้ได้65 ไบต์
Giuseppe


2

เยลลี่ , 8 7 ไบต์

ใช้⁺¿เพื่อส่งคืนองค์ประกอบที่ไม่เป็นศูนย์สุดท้าย (ขอบคุณ Dennis สำหรับ -1 ไบต์)

^Ḥ)i$⁺¿

ลองออนไลน์!

กำลังดุร้ายชนะอีกครั้ง :(


1
^Ḥ)i$⁺¿บันทึกเป็นไบต์
Dennis

และช้ากว่า 2x
user202729

2

C (gcc) , 57 56 55 51 ไบต์

  • บันทึกเป็นไบต์ขอบคุณไปที่catcat ; !=-.
  • บันทึกหนึ่งไบต์ห้าไบต์ด้วยRogem ; การใช้ประโยชน์จากการแสดงออกที่สามและนิสัยใจคอ gcc
X(O,R){for(R=1;R;O=R?R:O)for(R=O;--R&&(R^2*R)-O;);}

ลองออนไลน์!


1
+1 สำหรับX(O,R)
JayCe

@ceilingcat คำแนะนำที่ดีขอบคุณ
Jonathan Frech

for(R=1;R;O=R?R:O)บันทึกเป็นไบต์

R=O;ในตอนท้ายดูเหมือนว่าไม่จำเป็นช่วยให้คุณประหยัดอีก 4 ไบต์

@Rogem ดูเหมือนจะเป็นขอบคุณ
Jonathan Frech

2

Z80Golfขนาด 22 ไบต์

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

คำตอบ Java ของพอร์ตของ @ KevinCruijssen

ตัวอย่างที่มีการป้อนข้อมูลจาก 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ทั้งสองครั้งซึ่งจะช่วยประหยัดสองไบต์
Misha Lavrov


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 ขอบคุณ!
Kevin Cruijssen

1
38 ไบต์เขียนซ้ำ (ใช้ไม่ได้กับอินพุตที่ใหญ่กว่า):f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n
Neil


1

เยลลี่ , 11 9 ไบต์

BÄḂṛḄß$Ṫ?

ลองออนไลน์!

เคล็ดลับ: ใช้ฟังก์ชั่นวนซ้ำแทนการวนซ้ำ


เร็วมากโชคไม่ดีที่กำลังเข้าใกล้กำลังดุร้าย

โปรดทราบว่า:

  • สำหรับx> 0 , f (x)> x
  • popcount (f (x))เป็นเลขคู่โดยที่popcount (n)คือจำนวนบิตที่ตั้งค่าในn n
  • หากnมีจำนวน popcount เท่ากันแสดงว่ามีxเช่นนั้นที่ f (x) = nn
  • ให้B (x)เป็นเลขฐานสองของxและṖ (l)เป็น list lโดยที่เอาองค์ประกอบสุดท้ายออก แล้วB (x)เป็นแฮคเกอร์สะสมของP (B (f (x)))

ดังนั้นเราจึง:

  • คำนวณการแทนค่าฐานสองของมัน ( B)
  • จากนั้นใช้ XOR สะสม (ใช้^\หรือÄḂพวกเขามีผลเหมือนกัน)
  • ตรวจสอบว่า ( ?) ส่วนท้าย (องค์ประกอบสุดท้าย) ( ) ของ XOR ที่สะสมเป็นศูนย์ (popcount คี่)
    • ถ้าเป็นเช่นนั้นแปลงรายการเลขฐานสองกลับเป็นทศนิยมและเรียกคืน
    • ถ้าไม่ส่งคืนอินพุต ( )


1

Forth (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 ใด ๆ ในที่สุดจะถูกประเมินเป็น0เมื่อหารด้วย 2 ครั้งพอ (และส่วนทศนิยมจะถูกละเว้นเพียงเมื่อ XOR จะได้ดังนั้นสิ่งนี้จะไม่ส่งผลกระทบต่อผล)
Arnauld


@Shaggy ประหลาดใจว่ามันใช้งานได้ ฉันรู้ว่ามันใช้งานได้กับ Python และ Lua เป็นต้น แต่ไม่ใช่จาวาสคริปต์
user202729

การfalseส่งคืนในการทำซ้ำครั้งล่าสุดนั้นจะถูกส่งไปยัง0ผู้ควบคุม XOR
Shaggy

@Shaggy ในความเป็นจริงไม่มีfalseมีส่วนเกี่ยวข้อง JS ทำงานเกือบจะเหมือนกันหลาม&& / 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 ไบต์

ขึ้นอยู่กับ Java ของ Kevin Cruijssen:

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 ไบต์เหล่านี้ทำงานได้หรือไม่
ติตัส

0

ภาษา Wolfram (Mathematica) , 58 ไบต์

Min[{#}//.x_:>Select[Range@#,MemberQ[x,#|BitXor[#,2#]]&]]&

ลองออนไลน์!

เริ่มต้นด้วยรายการที่มีเพียงอินพุต วนซ้ำรายการโดยจำนวนเต็มทั้งหมดที่มีอยู่แล้วในนั้นหรือแมปเข้ากับมันโดยการดำเนินการสองครั้งและ xor จากนั้น//.บอกว่าจะทำเช่นนี้จนกว่าจะถึงจุดคงที่ คำตอบคือองค์ประกอบน้อยที่สุดของผลลัพธ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.