Tôi có phải là số Cullen không?


25

Số Cullen là bất kỳ số nào có trong chuỗi được tạo bằng công thức:

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

Nhiệm vụ của bạn:

Viết chương trình hoặc hàm nhận đầu vào và xuất giá trị trung thực / giả dựa trên việc đầu vào có phải là Số Cullen hay không.

Đầu vào:

Một số nguyên không âm trong khoảng từ 0 đến 10 ^ 9 (đã bao gồm).

Đầu ra:

Giá trị trung thực / giả mạo cho biết liệu đầu vào có phải là Số Cullen hay không.

Các trường hợp thử nghiệm:

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

Ghi điểm:

Đây là , vì vậy điểm số thấp nhất tính bằng byte sẽ thắng.


1
Phạm vi của n là gì? Cụ thể, 1 có phải là số Cullen không?

3
@ ais523 theo OEIS , nó là vậy. ndường như là dựa trên 0
steenbergh

Đủ công bằng. Chỉ cần biết câu trả lời Jelly của tôi nên có hoặc Rtrong đó :-)


Umm, những gì với downvote?
Gryphon - Phục hồi Monica

Câu trả lời:



16

Mã máy x86_64 ( Hệ thống V ABI ), 28 27 byte

-1 byte nhờ @Cody Gray, cảm ơn!

Một thuật toán không đổi thời gian!

_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

Giải trình:

Đặt y một số nguyên và x=y*2^y + 1. Lấy nhật ký, chúng tôi có y + log2(y) = log2(x-1), do đó y=log2(x-1)-log2(y). Cắm lại giá trị của y, chúng tôi nhận được y=log2(x-1)-log2(log2(x-1)-log2(y)). Làm điều này một lần nữa, chúng tôi có được : y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Hãy để chúng tôi xóa các điều khoản cuối cùng (theo thứ tự log2(log2(log2(log2(x)))), điều này sẽ an toàn!) Và giả sử rằng x-1≈x, chúng tôi có được: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Bây giờ, cho phép f(n) = floor(log2(n)), nó có thể được xác minh bằng tay ycó thể được truy xuất chính xác bằng cách : y=f(x)-f[f(x)-f(f(x))], cho y <26 , và do đó x ⩽ 10 ^ 9 , như được chỉ định bởi thử thách (1) .

Thuật toán sau đó chỉ đơn giản bao gồm tính toán y đã cho x và xác minh rằng x == y * 2 ^ y + 1 . Thủ thuật f(n)đơn giản là có thể được thực hiện như bsrhướng dẫn (quét ngược bit), trả về chỉ mục của 1 bit đầu tiên trong ny*2^ynhư y << y.

Mã chi tiết:

_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) Trên thực tế, sự bình đẳng này dường như giữ giá trị của y lên tới 50000.


4
Chà, tôi khá chắc chắn rằng điều này đủ điều kiện là mã thú vị nhất cho thử thách này cho đến nay. +1
Gryphon - Phục hồi Monica

1
Pre-XORing eaxsẽ cho phép bạn loại bỏ movzbl, tiết kiệm 1 byte. Tất nhiên, bạn cần phải thực hiện XOR cmplđể nó không bị treo cờ, nhưng điều đó hoàn toàn tốt vì không có gì sau đó phụ thuộc vào eax. Hoặc, bạn chỉ có thể quyết định rằng phương thức trả về Boolean chỉ trong 8 bit thấp hơn, tiết kiệm cả 3 byte!
Cody Grey

@CodyGray Thật vậy, cảm ơn rất nhiều :)
yoann

7

Thạch , 7 6 byte

Ḷæ«`i’

Hãy thử trực tuyến!

Đưa đầu vào làm đối số dòng lệnh. Nếu được cấp số Cullen C ( n ), xuất ra n +1 (là số thật trong Jelly, là số nguyên khác không; lưu ý rằng chúng ta có n ≥0 vì đầu vào là số nguyên và số Cullen có n âm không bao giờ là số nguyên) . Nếu được cung cấp một số không phải Cullen, trả về 0, đó là falsey trong Jelly.

Giải trình

Ḷæ«`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

Về cơ bản, tạo thành một mảng các số Cullen trừ đi một, sau đó tìm đầu vào trừ một số trong đó. Nếu đầu vào là số Cullen, chúng tôi sẽ tìm thấy nó, nếu không chúng tôi sẽ không. Lưu ý rằng mảng nhất thiết phải đủ dài để tiếp cận đầu vào, bởi vì C ( n ) luôn lớn hơn n .


7

JavaScript (ES6), 37 35 byte

Đã lưu 2 byte nhờ Neil

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

Bản giới thiệu


x<n?f(n,k+1):x==nhoạt động không?
Neil

@Neil Chắc chắn là có. :-)
Arnauld

Tại sao `~ k hoạt động, trong khi k + 1 làm quá tải nút gọi?
trlkly

@trlkly Về cơ bản, undefined+1===NaNnhưng -~undefined===1. Bạn có thể đọc thêm về điều này ở đây .
Arnauld


3

, 8 byte

@Dº*≥Dlε

Hãy thử trực tuyến!

           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

05AB1E , 7 byte

ÝDo*¹<å

Hãy thử trực tuyến!

Giải trình:

Ý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 byte

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

Chức năng ẩn danh. Kiểm tra nếu xđược tạo trong chuỗi C (n) cho n trong [0, x].

3 byte được chơi bởi Giuseppe.

Hãy thử trực tuyến!


sử dụng x%in%...thay vì any(x==...); sẽ giảm cho bạn 4 byte
Giuseppe

Vì vậy, nếu tôi đánh gôn điều này bằng cách thay đổi lapplythành chỉ đơn giản là kiểm tra vectơ và sử dụng scanthay vì lấy tham số hàm - tôi nhận được câu trả lời của @giuseppe. Cảm ơn bạn đã đăng riêng nó để tôi có thể thấy những gì tôi đang thiếu - tôi tìm hiểu thêm bằng cách tự mình thử một cái gì đó, mặc dù tôi thường bị mất.
BLT

3

C, C ++, Java, C #, D: 70 byte

Do sự tương đồng giữa tất cả các ngôn ngữ này, mã này hoạt động cho từng ngôn ngữ

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

Tôi sẽ đăng phiên bản D được tối ưu hóa lần này, một số thủ thuật dành riêng cho D có thể được sử dụng.
Zacharý

Đề xuất i=30;i--;)if(i<<i==n-1)thay vìi=0;i<30;++i)if((1<<i)*i+1==n)
trần mèo



2

R , 26 byte

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

Hãy thử trực tuyến!

Một cách tiếp cận hơi khác so với câu trả lời R khác ; đọc từ stdinvà vì đầu vào được đảm bảo trong khoảng từ 0 đến 10 ^ 9, chúng ta chỉ cần kiểm tra ntừ 0 đến 26.


Tôi không bao giờ nhớ scan(). Làm tốt lắm.
BLT

2

APL (Dyalog) , 9 byte

Để bao gồm trường hợp n = 1, nó yêu cầu ⎕IO←0mặc định trên nhiều hệ thống.

⊢∊1+⍳×2*⍳

Hãy thử trực tuyến!

 [là] n (đối số)

 một thành viên của

1 một

+ thêm

 các i ntegers 0 ... ( n -1)

× lần

2 hai

* với sức mạnh của

 các i ntegers 0 ... ( n -1)


Vậy, "mặc định trên nhiều hệ thống" có nghĩa là nó chỉ tồn tại ?
Zacharý

@ Zacharý Vâng, sẽ là sai nếu gọi ⎕IO←0không chuẩn, vì nhiều người thực sự luôn đặt nó như thế, không có thông số kỹ thuật cần thiết mỗi lần.
Adám

Tốt. Tôi chắc chắn sẽ sử dụng mánh khóe đó trong MY (và MY có thể có Nguồn gốc Index 0 và không 1) nếu tôi có cơ hội.
Zacharý

@ Zacharý Sẽ không yêu cầu cơ sở / phiên bản cài đặt thực tế trong đó các giá trị đó là mặc định? Ví dụ: trong SAX và ngn ⎕IO←0,.
Adám

Vâng, tôi đoán nó sẽ. Và MY có ba iotas, vì vậy tôi nghĩ rằng nó sẽ không được sử dụng.
Zacharý

2

Python 2 , 32 byte

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

Hãy thử trực tuyến!

Tạo danh sách các số Cullen tối đa 10^9, sau đó đếm số lần đầu vào xuất hiện trong đó. Cảm ơn Vincent đã chỉ ra n<<n|1thay vì (n<<n)+1, tiết kiệm 2 byte.


Bạn có thể lưu hai byte bằng cách sử dụng n<<n|1( n<<nchẵn);)
Vincent

Điều này thất bại cho 838860801. Bạn cần range(26), bởi vì phạm vi không bao gồm.
mbomb007

@ mbomb007 Cảm ơn. Tôi đã làm điều này trong một thời gian và đôi khi vẫn quên phạm vi là độc quyền.
xnor

2

D, 65 byte

Đây là một cổng của thuật toán @ HatsuPulumKun đến D (bản gốc đã là mã D, nhưng đây là với các thủ thuật dành riêng cho D)

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

Làm sao? (D thủ thuật cụ thể)

Hệ thống mẫu của D ngắn hơn C ++ và có thể suy ra các loại. Và D cũng khởi tạo các biến của nó thành mặc định khi khai báo.


1

Toán học, 30 byte

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

Hàm thuần túy lấy một số nguyên không âm làm đầu vào và trả về Truehoặc False. Nếu đầu vào là n, sau đó (r=Range@#-1)đặt biến rthành {0, 1, ..., n-1}, và sau đó r2^r+1tính toán một cách hợp lý các nsố Cullen đầu tiên . MemberQ[...,#]sau đó kiểm tra xem có phải nlà một thành phần của danh sách hay không.



1

VBA Excel, 45 byte

Chức năng cửa sổ ngay lập tức VBE ẩn danh đưa đầu vào từ ô [A1]và xuất ra cửa sổ ngay lập tức VBE

Phải được chạy trong một mô-đun sạch hoặc có các giá trị cho i, j được đặt lại về giá trị mặc định là 0 giữa các lần chạy

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

Đầu ra đầu vào

I / O như đã thấy trong cửa sổ VBE ngay lập tức

[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 byte

f(X)thành công nếu nó có thể tìm thấy giá trị I trong đó X = I * 2 ^ I + 1. Gợi ý phạm vi ngăn không cho nó hết dung lượng ngăn xếp, nhưng nó đủ cho phạm vi số Cullen lên tới 10 ^ 9 trong thông số câu hỏi.

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

ví dụ

f(838860801).
true


1

TI-BASIC, 17 byte

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

Giải trình

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

Bạn có thể muốn thêm một lời giải thích cho điều này.
Gryphon - Tái lập Monica

Xong, cảm ơn vì tiền boa.
calc84maniac

Điều đó hoạt động, nhưng một lời giải thích theo lệnh thường giúp thu được hầu hết các upvote. Tôi sẽ khuyên bạn nên làm một cái gì đó như lời giải thích về câu trả lời này . Tôi không biết tại sao ai đó đánh giá thấp bài viết của bạn mặc dù. Đó thường là phép lịch sự phổ biến để để lại nhận xét khi bạn làm như vậy, mặc dù ý tưởng đó thường bị bỏ qua.
Gryphon - Tái lập Monica

Chào mừng bạn Tôi nhớ khi tôi mới tham gia trang web, mọi người đã nói với tôi những điều này. Chỉ cần chuyển qua ủng hộ.
Gryphon - Tái lập Monica

0

QBIC , 24 byte

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

Giải trình

[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 byte

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

Hãy thử trực tuyến. Truthy là một mảng có một số trong đó: ,3hoặc ,0et cetera. Falsey là một mảng trống: ()hoặc !0tùy thuộc vào thông dịch viên của bạn.



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.