나는 컬린 번호인가?


25

Cullen Number는 수식을 사용하여 생성 된 시퀀스에 포함 된 숫자입니다.

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

당신의 작업 :

입력이 Cullen Number인지 여부에 따라 입력을 수신하고 참 / 거짓 값을 출력하는 프로그램 또는 함수를 작성하십시오.

입력:

0에서 10 ^ 9 사이의 음이 아닌 정수 (포함)입니다.

산출:

입력이 Cullen Number인지를 나타내는 참 / 거짓 값입니다.

테스트 사례 :

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

채점 :

이것은 이므로 바이트 단위의 최저 점수가 이깁니다.


1
n 의 범위는 무엇입니까 ? 특히, 1은 컬린 번호입니까?

3
OEIS 에 따르면 @ ais523 입니다. n0 기반 인 것 같습니다.
steenbergh 2016 년

충분합니다. 내 젤리 답변에 : 또는)이 있어야하는지 알아야합니다. R:-)


음, downvote는 무엇입니까?
그리폰-복원 모니카

답변:



16

x86_64 머신 코드 ( System V ABI ), 28 27 바이트

@Cody Gray 덕분에 -1 바이트, 감사합니다!

일정한 시간 알고리즘!

_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

설명:

하자 Y에게 정수를하고 x=y*2^y + 1. y + log2(y) = log2(x-1)따라서 로그를 가져 와서 y=log2(x-1)-log2(y). 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))]

이제 챌린지 (1)에 의해 지정된대로 y <26에 대해 정확하게 검색 할 수 있고 따라서 x ⩽ 10 ^ 9 로 정확하게 검색 할 수 있는지 f(n) = floor(log2(n))수동으로 확인할 y수 있습니다 .y=f(x)-f[f(x)-f(f(x))]

그러면 알고리즘은 단순히 x가 주어진 y 계산으로 구성 되고 x == y * 2 ^ y + 1인지 확인 합니다. 트릭 즉 간단하게 구현 될 수 있는 제 1 비트의 인덱스를 반환 명령 (비트 주사 후진), N , 및 등 .f(n)bsry*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 값 을 50000까지 보유하는 것으로 보입니다 .


4
글쎄, 나는 이것이 지금 까지이 도전에 대한 가장 흥미로운 코드로 자격이 있다고 확신합니다. +1
그리폰-복원 모니카

1
사전 XORing eax을 사용하면을 제거하고 movzbl1 바이트를 절약 할 수 있습니다 . 물론 XOR을 수행해야 cmpl플래그를 방해하지 않지만 그 이후에는 아무것도 의존하지 않기 때문에 완전히 괜찮습니다 eax. 또는 메소드가 하위 8 비트만으로 부울을 리턴하여 3 바이트를 모두 저장하도록 결정할 수 있습니다.
코디 그레이

@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 숫자에서 1을 뺀 배열을 구성한 다음 입력에서 1을 뺀 값을 찾으십시오. 입력이 컬린 (Cullen) 번호이면 찾을 수 있고 그렇지 않으면 찾을 수 없습니다. C ( n )은 항상 n 보다 크기 때문에 배열은 입력에 도달 할 수있을 정도로 길어야 합니다.


7

자바 스크립트 (ES6), 37 35 바이트

Neil 덕분에 2 바이트 절약

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

데모


합니까의 x<n?f(n,k+1):x==n작업?
Neil

@ 닐 확실합니다. :-)
Arnauld 2016 년

왜 ~~ 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

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 바이트

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

익명의 기능. x시퀀스 C (n)에서 [0, x]의 n에 대해 생성 되는지 확인합니다 .

주세페가 3 바이트 골프를 쳤다.

온라인으로 사용해보십시오!


x%in%...대신에 사용 any(x==...); 그것은 당신에게 4 바이트를 떨어 뜨릴 것입니다
Giuseppe

그래서 lapply단순히 벡터를 확인 하도록 to를 변경하여 골프를 치고 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)
천장 고양이




2

APL (Dyalog) , 9 바이트

n = 1 의 경우를 처리하려면 ⎕IO←0많은 시스템에서 기본값이 필요 합니다.

⊢∊1+⍳×2*⍳

온라인으로 사용해보십시오!

 [is] n (인수)

 의 회원

1 하나

+ ...을 더한

I ntegers 0 .. ( N -1)

× 타임스

2 두

* ~의 힘으로

I ntegers 0 .. ( N -1)


따라서 "많은 시스템의 기본값"은 그것이 존재 한다는 것을 의미 합니다 .
Zacharý

@ Zacharý 그렇습니다. ⎕IO←0비표준 이라고 부르는 것은 틀릴 것입니다. 많은 사람들이 매번 사양이 없어도 항상 그렇게 설정되어 있기 때문입니다.
Adám

잘. 내가 기회를 얻는다면 나는 확실히 그 트릭을 MY에서 사용할 것입니다 (그리고 MY는 0이 아닌 인덱스 원점을 가질 수 있습니다).
Zacharý

@ Zacharý이 값이 기본값 인 실제 설치 기반 / 버전이 필요하지 않습니까? 예를 들어 SAX 및 ngn에서 ⎕IO←0.
Adám

그래, 그런 것 같아 그리고 내 3 개의 iota가 있으므로 어쨌든 사용되지 않을 것이라고 생각합니다.
Zacharý

2

파이썬 2 , 32 바이트

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

온라인으로 사용해보십시오!

Cullen 숫자 목록을 최대로 10^9만든 다음 입력이 몇 번 나타나는지 계산합니다. n<<n|1대신 (n<<n)+12 바이트를 절약 해 준 Vincent에게 감사 합니다.


다음을 사용하여 2 바이트를 저장할 수 있습니다 n<<n|1( n<<n심지어되는))
빈센트

에 실패합니다 838860801. 당신은 필요한 range(26)범위를 포함하지 않기 때문에.
mbomb007

감사합니다. 나는 이것을 잠시 동안 해왔고 때로는 범위가 권리 배타적이라는 것을 잊어 버립니다.
xnor

2

D, 65 바이트

이것은 @HatsuPointerKun 알고리즘의 D 포트입니다 (원본은 이미 D 코드이지만 D 관련 트릭이 있습니다)

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,#]&

입력 및 재로서 음수 일 복용 순수 기능 True이상 False. 입력이 n(r=Range@#-1)경우 변수 r를로 설정 {0, 1, ..., n-1}한 다음 r2^r+1첫 번째 n컬린 수 를 벡터 적으로 계산합니다 . MemberQ[...,#]그런 다음 n목록의 요소 인지 확인합니다 .



1

Excel VBA, 45 바이트

[A1]및 출력에서 ​​VBE 즉시 창으로 입력을받는 익명 VBE 즉시 창 기능

클린 모듈에서 실행되거나 i, j에 대한 값이 실행 사이에 기본값 0으로 재설정되어야합니다.

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

입출력

VBE 즉시 창에 표시되는 I / O

[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)X = I * 2 ^ I + 1 인 I 값을 찾을 수 있으면 성공합니다. 범위 힌트는 스택 공간 부족을 중지하지만 질문 사양에서 Cullen 숫자 범위는 최대 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

이에 대한 설명을 추가 할 수 있습니다.
그리폰 - 분석 재개 모니카

끝, 감사합니다.
calc84maniac

작동하지만 명령 별 설명은 일반적으로 대부분의 공감을 얻는 데 도움이됩니다. 이 답변 에 대한 설명과 같은 작업을 수행하는 것이 좋습니다. 왜 누군가가 귀하의 게시물을 하향 조정했는지 모르겠습니다. 일반적으로 그렇게 할 때 의견을 남기는 것이 일반적이지만, 그 아이디어는 종종 무시됩니다.
그리폰-복원 모니카

천만에요. 사이트에 처음 가입했을 때 사람들이 이런 종류의 이야기를 나에게 말했습니다. 호의를 전달하십시오.
그리폰-복원 모니카

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.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.