私はカレン番号ですか?


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はカレン数ですか?

3
OEISによると@ ais523 です。n0ベースのようです。
steenbergh

けっこうだ。ちょうど私のゼリーの答えは持っている必要があるかどうかを知るために必要な、またはRそれで:-)


うーん、下票とは何ですか?
グリフォン-モニカの復活

回答:



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))]

今、せるf(n) = floor(log2(n))、それは手動で検証することができるy:正確によって取得することができる y=f(x)-f[f(x)-f(f(x))]ため、Y <26、及び従ってX⩽10 ^ 9、チャレンジによって指定される(1)

アルゴリズムは、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
事前XOR eaxを使用すると、を削除してmovzbl1バイト節約できます。XORを前に実行する必要があるcmplので、もちろんフラグを無効にしませんが、それ以降はに依存しないため、まったく問題ありませんeax。または、メソッドが下位8ビットのみでブール値を返し、3バイトすべてを保存することを決定することもできます!
コーディグレー

@CodyGray確かに、ありがとう:)
yoann

7

ゼリー7 6バイト

Ḷæ«`i’

オンラインでお試しください!

入力をコマンドライン引数として受け取ります。カレン数C(与えられた場合、N)、出力N(;我々が持っていることに留意されたいゼリーでtruthyで、ゼロ以外の整数+1 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

基本的に、カレン数マイナス1の配列を作成し、その中の入力マイナス1を探します。入力がカレン数の場合、それを見つけますが、そうでない場合は見つかりません。C(n)は常にnよりも大きいため、配列は必然的に入力に到達するのに十分な長さであることに注意してください。


7

JavaScript(ES6)、37 35バイト

ニールのおかげで2バイト節約

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

デモ


DOESのx<n?f(n,k+1):x==n作品?
ニール

@Neilそれは確かです。:-)
アーナウド

なぜ `〜kは機能するのに、k + 1はコールスタックをオーバーロードするのですか?
trlkly

@trlkly基本的にはですundefined+1===NaN-~undefined===1。あなたはできるここにこのについての詳細を読みます
アーナルド


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

R53 51 46バイト

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

匿名関数。x[0、x]のnに対してシーケンスC(n)で生成されているかどうかをチェックします。

ジュゼッペがゴルフした3バイト。

オンラインでお試しください!


x%in%...代わりに使用しany(x==...)ます。4バイトをドロップします
ジュゼッペ

だから、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固有のトリックを使用できます。
ザカリー

提案するi=30;i--;)if(i<<i==n-1)代わりにi=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat




2

APL(Dyalog)、9バイト

n = 1の場合をカバーする⎕IO←0には、多くのシステムでどちらがデフォルトであるかが必要です。

⊢∊1+⍳×2*⍳

オンラインでお試しください!

 [is] n(引数)

 のメンバー

1 1

+ プラス

ntegers 0 ...(N -1)

× 回

2 二

* の力に

ntegers 0 ...(N -1)


それで、「多くのシステムのデフォルト」は、それがただ存在することを意味しますか?
ザカリー

@Zacharýはい、⎕IO←0非標準を呼び出すのは間違っています。多くの場合、常にそのように設定されており、毎回指定する必要はありません。
アダム

まあ。機会があれば、MYでそのトリックを確実に使用します(また、MYは0以外および1以外のインデックスオリジンを持つことができます)。
ザカリー

@Zacharýこれらの値がデフォルトである実際のインストールベース/バージョンは必要ないでしょうか?たとえば、SAXおよびngnの場合⎕IO←0
アダム

ええ、そうだと思います。そしてMYには3つのiotasがあるので、とにかくそれは使用されないと思います。
ザカリー

2

Python 2、32バイト

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

オンラインでお試しください!

Cullen数のリストを作成し10^9、そこに入力が表示される回数をカウントします。のn<<n|1代わりに指摘してくれたVincentに感謝し(n<<n)+1ます。2バイト節約します。


n<<n|1n<<n偶数)を使用して2バイトを保存できます;)
ビンセント

これは失敗し838860801ます。range(26)範囲が含まれていないため、必要です。
mbomb007

@ 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を見つけることができれば成功します。範囲のヒントにより、スタックスペースが不足することはありませんが、質問仕様では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.