ฉันเป็นหมายเลขคัลเลนหรือไม่


25

หมายเลขคัลเลนคือหมายเลขใด ๆ ที่อยู่ในลำดับที่สร้างโดยใช้สูตร:

C (n) = (n * 2 ^ n) +1

งานของคุณ:

เขียนโปรแกรมหรือฟังก์ชั่นที่รับอินพุตและส่งออกค่าความจริง / ผิดพลาดโดยพิจารณาจากอินพุตเป็นหมายเลขคัลเลน

การป้อนข้อมูล:

จำนวนเต็มที่ไม่เป็นลบระหว่าง 0 ถึง 10 ^ 9 (รวม)

เอาท์พุท:

ค่าความจริง / เท็จที่ระบุว่าอินพุตเป็นหมายเลขคัลเลน

กรณีทดสอบ:

Input:    Output:
1   --->  truthy
3   --->  truthy
5   --->  falsy
9   --->  truthy
12  --->  falsy
25  --->  truthy

เกณฑ์การให้คะแนน:

นี่คือดังนั้นคะแนนต่ำสุดเป็นไบต์ชนะ


1
ช่วงของnคืออะไร? โดยเฉพาะอย่างยิ่ง 1 หมายเลข Cullen คืออะไร?

3
@ ais523 ตามOEISมันเป็น nน่าจะเป็นแบบ 0
steenbergh

ยุติธรรมพอสมควร เพียงแค่ต้องรู้ว่าคำตอบของฉันเยลลี่ควรมีหรือRอยู่ในนั้น :-)


อืมอะไรคือ downvote?
Gryphon - Reinstate Monica

คำตอบ:



16

x86_64 รหัสเครื่อง ( System V ABI ), 28 27 ไบต์

-1 ไบต์ต้องขอบคุณ @Cody Gray ขอบคุณ!

อัลกอริทึมคงที่!

_cullen:
   0:   0f bd cf    bsrl    %edi, %ecx
   3:   0f bd c1    bsrl    %ecx, %eax
   6:   89 ca       movl    %ecx, %edx
   8:   29 c2       subl    %eax, %edx
   a:   0f bd c2    bsrl    %edx, %eax
   d:   29 c1       subl    %eax, %ecx
   f:   d3 e1       shll    %cl, %ecx
  11:   ff c1       incl    %ecx
  13:   31 c0       xorl    %eax, %eax
  15:   39 f9       cmpl    %edi, %ecx
  17:   0f 94 c0    sete    %al
  1a:   c3          retq

คำอธิบาย:

Let Yx=y*2^y + 1เป็นจำนวนเต็มและ บันทึกการเรามีจึงy + log2(y) = log2(x-1) เสียบกลับค่าของปีที่เราได้รับy=log2(x-1)-log2(y) y=log2(x-1)-log2(log2(x-1)-log2(y))การทำเช่นนี้อีกครั้งเราได้รับ: y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

ให้เราลบคำสุดท้าย (ตามลำดับของlog2(log2(log2(log2(x))))สิ่งนี้ควรจะปลอดภัย!) และสมมติว่าx-1≈xเราได้รับ: y≈log2(x)-log2[log2(x)-log2(log2(x))]

ตอนนี้ให้f(n) = floor(log2(n))มันสามารถตรวจสอบได้ด้วยตนเองที่yสามารถเรียกดูได้ว่าโดย: y=f(x)-f[f(x)-f(f(x))]สำหรับปี <26และทำให้x ⩽ 10 ^ 9ตามที่ระบุไว้โดยความท้าทาย(1)

ขั้นตอนวิธีการนั้นก็ประกอบด้วยคอมพิวเตอร์Yให้xและตรวจสอบว่าx == Y * 2 ^ Y + 1 เคล็ดลับคือการที่f(n)สามารถจะดำเนินการในขณะที่bsrการเรียนการสอน (บิตสแกนย้อนกลับ) ซึ่งผลตอบแทนดัชนีแรก 1 บิตในnและเป็นy*2^yy << y

รหัสรายละเอียด:

_cullen:                                 ; int cullen(int x) {
   0:   0f bd cf    bsrl    %edi, %ecx   ;  int fx = f(x);
   3:   0f bd c1    bsrl    %ecx, %eax   ;  int ffx = f(f(x));
   6:   89 ca       movl    %ecx, %edx   
   8:   29 c2       subl    %eax, %edx   ;  int a = fx - ffx;
   a:   0f bd c2    bsrl    %edx, %eax   ;  int ffxffx = f(a);
   d:   29 c1       subl    %eax, %ecx   ;  int y = fx - ffxffx;
   f:   d3 e1       shll    %cl, %ecx    ;  int x_ = y<<y;
  11:   ff c1       incl    %ecx         ;  x_++;
  13:   31 c0       xorl    %eax, %eax
  15:   39 f9       cmpl    %edi, %ecx
  17:   0f 94 c0    sete    %al
  1a:   c3          retq                 ;  return (x_ == x);
                                         ; }

(1)อันที่จริงความเท่าเทียมกันนี้ดูเหมือนจะเก็บค่าyถึง 50,000 ได้


4
ฉันค่อนข้างมั่นใจว่านี่เป็นคุณสมบัติที่เป็นรหัสที่น่าสนใจที่สุดสำหรับความท้าทายนี้ +1
Gryphon - Reinstate Monica

1
Pre-XORing eaxจะช่วยให้คุณกำจัดการmovzblบันทึก 1 ไบต์ คุณจะต้องทำแฮคเกอร์ก่อนcmplจึงไม่ข่มขี่ธงแน่นอน eaxแต่ที่ดีโดยสิ้นเชิงเพราะไม่มีอะไรหลังจากนั้นขึ้นอยู่กับ หรือคุณสามารถตัดสินใจได้ว่าวิธีการคืนค่าบูลีนในบิตที่ต่ำกว่าเพียง 8 บิตประหยัดทั้ง 3 ไบต์!
Cody Grey

@CodyGray แน่นอนขอบคุณมาก :)
yoann

7

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

Ḷæ«`i’

ลองออนไลน์!

รับอินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง หากได้รับเป็นจำนวนคัลเลน C ( n ) เอาท์พุทn +1 (ซึ่งเป็น truthy ในเยลลี่เป็นจำนวนเต็มภัณฑ์; ทราบว่าเรามีn ≥0เพราะการป้อนข้อมูลที่เป็นจำนวนเต็มและตัวเลขคัลเลนกับเชิงลบnจะไม่จำนวนเต็ม) . หากได้รับหมายเลขที่ไม่ใช่คัลเลนจะส่งคืนค่า 0 ซึ่งเป็นเท็จในเจลลี่

คำอธิบาย

Ḷæ«`i’
Ḷ        Form a range from 0 to (the input minus 1)
 æ«      Left-shift each element in the range by 
   `       itself
    i’   Look for (the input minus 1) in the resulting array

โดยทั่วไปจัดรูปแบบของตัวเลข Cullen ลบหนึ่งจากนั้นมองหาอินพุตลบหนึ่งในนั้น หากการป้อนข้อมูลเป็นหมายเลขคัลเลนเราจะพบมันมิฉะนั้นเราจะไม่ โปรดทราบว่าอาร์เรย์จำเป็นต้องยาวพอที่จะเข้าถึงการป้อนข้อมูลเพราะ C ( n ) อยู่เสมอมากกว่าn


7

JavaScript (ES6), 37 35 ไบต์

บันทึก 2 ไบต์ต้องขอบคุณ Neil

f=(n,k,x=k<<k^1)=>x<n?f(n,-~k):x==n

การสาธิต


ไม่x<n?f(n,k+1):x==nทำงานหรือไม่
Neil

@ ไม่มีมันแน่นอน :-)
Arnauld

ทำไม `~ k ทำงานในขณะที่ k + 1 เรียกสแต็คเกินพิกัด
trlkly

@trlkly โดยทั่วไปแต่undefined+1===NaN -~undefined===1คุณสามารถอ่านรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่
Arnauld


3

โอห์ม 8 ไบต์

@Dº*≥Dlε

ลองออนไลน์!

           Implicit input
@          Range [1,...,Input]
 D         Duplicate
  º        2^n each element
   *       Multiply those two array
    ≥      Increment everything (now I have an array of all Cullen Numbers)
     Dl    Push array length (= get input again, can't get again implicitly or using a function because it would be a string so I'd waste a byte again)
       ε   Is input in array?

3

PHP , 43 ไบต์

for(;$argn>$c=1+2**$n*$n++;);echo$argn==$c;

ลองออนไลน์!


คือ$argnตัวแปรพิเศษหรือไม่? การเปลี่ยนเป็น$aบันทึกจะมีขนาด 6 ไบต์: tio.run/##K8go@G9jX5BRwKWSaKtkaGaoZP0/…
topher

@topher ใช่ $argnสามารถใช้ได้ถ้าคุณเรียกใช้ PHP จากบรรทัดคำสั่งพร้อมกับ-Rตัวเลือก
JörgHülsermann

3

05AB1E , 7 ไบต์

ÝDo*¹<å

ลองออนไลน์!

คำอธิบาย:

ÝDo*¹<å Example input: 9. Stack: [9]
Ý       Range 0-input. Stack: [[0,1,2,3,4,5,6,7,8,9]]
 D      Duplicate. Stack: [[0,1,2,3,4,5,6,7,8,9],[0,1,2,3,4,5,6,7,8,9]]
  o     2** each item in the list. Stack: [[0,1,2,3,4,5,6,7,8,9], [1,2,4,8,16,32,64,128,256,512]]
   *    Multiply the two lists. Stack: [[0, 2, 8, 24, 64, 160, 384, 896, 2048, 4608]]
    ¹   Push input again. Stack: [[0, 2, 8, 24, 64, 160, 384, 896, 2048, 4608],9]
     <  Decrement. Stack: [[0, 2, 8, 24, 64, 160, 384, 896, 2048, 4608],8]
      å Is the first item of the stack in the second item? Stack: [1]
        Implicit print.

3

R , 53 51 46 46 ไบต์

pryr::f(x%in%lapply(0:x,function(y)(y*2^y+1)))

ฟังก์ชั่นไม่ระบุชื่อ ตรวจสอบว่าxถูกสร้างขึ้นในลำดับ C (n) สำหรับ n ใน [0, x]

3 ไบต์ golfed โดย Giuseppe

ลองออนไลน์!


ใช้x%in%...แทนany(x==...); นั่นจะทำให้คุณลดลง 4 ไบต์
Giuseppe

ดังนั้นถ้าฉันตีกอล์ฟด้วยการเปลี่ยนเป็นlapplyเพียงแค่ตรวจสอบเวกเตอร์และใช้scanแทนการโต้แย้งฟังก์ชั่น - ฉันได้รับคำตอบของ @giuseppe ขอขอบคุณที่โพสต์แยกต่างหากเพื่อให้ฉันเห็นสิ่งที่ขาดหายไป - ฉันเรียนรู้เพิ่มเติมโดยทดลองใช้ด้วยตัวเองถึงแม้ว่าฉันจะแพ้ก็ตาม
BLT

3

C, C ++, Java, C #, D: 70 ไบต์

เนื่องจากความคล้ายคลึงกันระหว่างภาษาเหล่านี้ทั้งหมดรหัสนี้ทำงานสำหรับแต่ละภาษา

int c(int n){for(int i=0;i<30;++i)if((1<<i)*i+1==n)return 1;return 0;}

ฉันจะโพสต์รุ่น D ที่ปรับให้เหมาะสมแล้วในเวลานี้มีเทคนิคเฉพาะ D สวย ๆ ที่สามารถใช้ได้
Zacharý

แนะนำi=30;i--;)if(i<<i==n-1)แทนi=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat


2

Python 2 , 36 ไบต์

f=lambda n,i=0:i<<i!=n-1and f(n,i+1)

ลองออนไลน์!

เอาต์พุตโดยไม่หยุดทำงาน / หยุดทำงานดังที่ได้รับอนุญาตในขณะนี้โดยการทำข้อตกลงเมตานี้


Python 2 , 42 ไบต์

i=0
n=input()-1
while i<<i<n:i+=1
i<<i>n<c

ลองออนไลน์!

ส่งออกผ่านรหัสทางออก


2

R , 26 ไบต์

a=0:26;scan()%in%(1+a*2^a)

ลองออนไลน์!

วิธีที่แตกต่างเล็กน้อยกว่าคำตอบ R อื่น ๆ ; อ่านจากstdinและเนื่องจากอินพุตมีการรับประกันว่าอยู่ระหว่าง 0 ถึง 10 ^ 9 เราเพียงต้องตรวจสอบnระหว่าง 0 ถึง 26


ฉันไม่เคยจำscan()ได้ การทำงานที่ดี.
BLT

2

APL (Dyalog)ขนาด 9 ไบต์

เพื่อครอบคลุมกรณีของn = 1 จะต้องใช้⎕IO←0ซึ่งเป็นค่าเริ่มต้นในหลายระบบ

⊢∊1+⍳×2*⍳

ลองออนไลน์!

 [คือ] n (อาร์กิวเมนต์)

 สมาชิกของ

1 หนึ่ง

+ บวก

 the i ntegers 0 … ( n -1)

× ครั้ง

2 สอง

* ถึงพลังของ

 the i ntegers 0 … ( n -1)


ดังนั้น "ค่าเริ่มต้นในหลาย ๆ ระบบ" หมายความว่ามันมีอยู่แล้ว ?
Zacharý

@ Zacharýใช่มันผิดที่จะโทรหาคนที่⎕IO←0ไม่ได้มาตรฐานเพราะหลาย ๆ คนมักจะตั้งไว้อย่างนั้นโดยไม่จำเป็นต้องมีข้อกำหนดในแต่ละครั้ง
อดัม

ดี. ฉันจะใช้เคล็ดลับนั้นใน MY แน่นอน (และ MY สามารถมีต้นกำเนิดดัชนีที่ไม่ใช่ 0 และไม่ใช่ -1) ถ้าฉันได้รับโอกาส
Zacharý

@ Zacharýนั่นไม่จำเป็นต้องมีฐานการติดตั้งจริง / รุ่นที่ค่าเหล่านั้นเป็นค่าเริ่มต้น? เช่นในแซ็กโซโฟนและ ⎕IO←0NGN,
2560

ใช่ฉันคิดว่ามันจะ ของฉันมีสามไอโซโทปดังนั้นฉันคิดว่ามันจะไม่ถูกใช้ต่อไป
Zacharý

2

Python 2 , 32 ไบต์

[n<<n|1for n in range(26)].count

ลองออนไลน์!

สร้างรายการหมายเลขคัลเลนถึง10^9แล้วนับจำนวนครั้งที่อินพุตปรากฏในนั้น ขอบคุณ Vincent ที่ชี้ให้เห็นn<<n|1แทนที่จะ(n<<n)+1ช่วยให้ประหยัด 2 ไบต์


คุณสามารถบันทึกสองไบต์โดยใช้n<<n|1( n<<nกำลังเท่ากัน);)
Vincent

838860801นี้ล้มเหลว คุณต้องการrange(26)เนื่องจากช่วงไม่รวมอยู่ด้วย
mbomb007

@ mbomb007 ขอบคุณ ฉันเคยทำสิ่งนี้มาระยะหนึ่งแล้วและบางครั้งก็ยังลืมไปว่า
xnor

2

D, 65 ไบต์

นี่คือพอร์ตของอัลกอริทึมของ @ HatsuPointerKun ถึง D (ต้นฉบับคือรหัส D อยู่แล้ว แต่นี่เป็นกลอุบาย D-specific)

T c(T)(T n){for(T i;i<30;++i)if((1<<i)*i+1==n)return 1;return 0;}

อย่างไร? (เทคนิคเฉพาะ D)

ระบบแม่แบบของ D นั้นสั้นกว่า C ++ และสามารถอนุมานชนิดได้ และ D ยังเริ่มต้นตัวแปรเป็นค่าเริ่มต้นเมื่อมีการประกาศ


1

Mathematica ขนาด 30 ไบต์

MemberQ[(r=Range@#-1)2^r+1,#]&

ฟังก์ชั่นเพียวการติดลบเป็น input และกลับมาหรือTrue Falseถ้าอินพุตnนั้นให้(r=Range@#-1)ตั้งค่าตัวแปรrเป็น{0, 1, ..., n-1}แล้วr2^r+1คำนวณเวกเตอร์nหมายเลขคัลเลนแรก MemberQ[...,#]จากนั้นตรวจสอบว่าnเป็นองค์ประกอบของรายการหรือไม่



1

Excel VBA ขนาด 45 ไบต์

ฟังก์ชันหน้าต่าง VBE แบบไม่ระบุชื่อทันทีที่รับอินพุตจากเซลล์[A1]และ ouputs ไปยังหน้าต่างทันที VBE

จะต้องทำงานในโมดูลที่สะอาดหรือมีค่าสำหรับ i, j จะถูกรีเซ็ตเป็นค่าเริ่มต้นของ 0 ระหว่างการทำงาน

While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]

อินพุต / เอาต์พุต

I / O ดังที่เห็นในหน้าต่าง VBE ทันที

[A1]=25
While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]
True

[A1]=1: i=0:j=0 ''# clearing module values
While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]
True    

[A1]=5: i=0:j=0 ''# clearing module values
While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]
False 

1

Swi-Prolog, 69 ไบต์

f(X)สำเร็จหากสามารถหาค่า I โดยที่ X = I * 2 ^ I + 1 คำใบ้ช่วงหยุดการใช้พื้นที่สแต็ก แต่ก็เพียงพอสำหรับช่วงหมายเลขคัลเลนถึง 10 ^ 9 ในข้อมูลจำเพาะของคำถาม

:-use_module(library(clpfd)).
f(X):-I in 0..30,X#=I*2^I+1,label([I]).

เช่น

f(838860801).
true


1

TI-BASIC ขนาด 17 ไบต์

max(Ans=seq(X2^X+1,X,0,25

คำอธิบาย

seq(X2^X+1,X,0,25 Generate a list of Cullen numbers in the range
Ans=              Compare the input to each element in the list, returning a list of 0 or 1
max(              Take the maximum of the list, which is 1 if any element matched

คุณอาจต้องการเพิ่มคำอธิบายลงในสิ่งนี้
Gryphon - Reinstate Monica

เสร็จแล้วขอบคุณสำหรับเคล็ดลับ
calc84maniac

ใช้งานได้ แต่คำอธิบายแบบคำสั่งคำสั่งมักจะช่วยให้สะสม upvotes ได้มากที่สุด ฉันขอแนะนำให้ทำบางอย่างเช่นคำอธิบายในคำตอบนี้ ฉันไม่รู้ว่าทำไมมีคนลงโพสต์ของคุณ โดยทั่วไปแล้วมารยาททั่วไปที่จะแสดงความคิดเห็นเมื่อคุณทำเช่นนั้นถึงแม้ว่าความคิดนั้นมักจะถูกละเลย
Gryphon - Reinstate Monica

ยินดีต้อนรับ. ฉันจำได้เมื่อฉันเข้าร่วมครั้งแรกผู้คนบอกสิ่งเหล่านี้กับฉัน เพียงผ่านความโปรดปราน
Gryphon - Reinstate Monica

0

QBICขนาด 24 ไบต์

[0,:|~a*(2^a)+1=b|_Xq}?0

คำอธิบาย

[0,:|           FOR a = 0 to b (input from cmd line)
~a*(2^a)+1=b    IF calculating this a results in b
|_Xq            THEN quit, printing 1
}               NEXT a
?0              We haven't quit early, so print 0 and end.

0

k , 19 ไบต์

{&1=x-{x**/x#2}'!x}

ลองออนไลน์ Truthy เป็นอาร์เรย์ที่มีตัวเลขอยู่: ,3หรือ,0อื่น ๆ Falsey เป็นอาร์เรย์ที่ว่างเปล่า: ()หรือ!0ขึ้นอยู่กับล่ามของคุณ



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