Bin ich eine Cullen-Nummer?


25

Eine Cullen-Zahl ist eine beliebige Zahl, die in der mit folgender Formel erzeugten Sequenz enthalten ist:

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

Deine Aufgabe:

Schreiben Sie ein Programm oder eine Funktion, die eine Eingabe empfängt und einen Wahrheits- / Falschwert ausgibt, basierend darauf, ob die Eingabe eine Cullen-Zahl ist.

Eingang:

Eine nicht negative ganze Zahl zwischen 0 und 10 ^ 9 (einschließlich).

Ausgabe:

Ein wahrer / falscher Wert, der angibt, ob die Eingabe eine Cullen-Zahl ist.

Testfälle:

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

Wertung:

Das ist , also gewinnt die niedrigste Punktzahl in Bytes.


1
Was ist der Bereich von n ? Insbesondere ist 1 eine Cullen-Zahl?

3
@ ais523 laut OEIS ist es. nscheint 0-basiert zu sein.
Steenbergh

Meinetwegen. Ich musste nur wissen, ob meine Gelee-Antwort eine oder eine enthalten sollte R:-)


Ähm, was ist mit der Gegenstimme?
Gryphon - Setzen Sie Monica am

Antworten:



16

x86_64-Maschinencode ( System V ABI ), 28 27 Byte

-1 Byte danke an @Cody Gray, danke!

Ein Algorithmus mit konstanter Zeit!

_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

Erläuterung:

Sei y eine ganze Zahl und x=y*2^y + 1. Protokolle nehmen, haben wir y + log2(y) = log2(x-1)also y=log2(x-1)-log2(y). Wenn wir den Wert von y zurücksetzen, erhalten wir y=log2(x-1)-log2(log2(x-1)-log2(y)). Dadurch noch einmal, so erhalten wir: y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Entfernen wir die letzten Begriffe (in der Größenordnung von log2(log2(log2(log2(x)))), das sollte sicher sein!) Und gehen x-1≈xwir davon aus, dass wir erhalten: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Nun f(n) = floor(log2(n))kann manuell überprüft werden, ob ygenau abgerufen werden kann durch: y=f(x)-f[f(x)-f(f(x))]für y <26 und somit x x 10 ^ 9 , wie durch die Abfrage (1) angegeben .

Der Algorithmus besteht dann einfach darin, y mit gegebenem x zu berechnen und zu überprüfen, ob x == y * 2 ^ y + 1 ist . Der Trick ist, dass f(n)einfach als bsrBefehl (Bit-Scan-Reverse) implementiert werden kann , der den Index des ersten 1-Bit in n und y*2^yas zurückgibt y << y.

Ausführlicher Code:

_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) Tatsächlich scheint diese Gleichheit für Werte von y bis 50000 zu gelten.


4
Ich bin mir ziemlich sicher, dass dies der interessanteste Code für diese Herausforderung ist. +1
Gryphon - Reinstate Monica

1
Pre-XORing eaxwürde es Ihnen ermöglichen, die movzblEinsparung von 1 Byte zu eliminieren . Sie müssten das XOR vor dem cmplausführen, damit die Flags nicht verstopfen, aber das ist völlig in Ordnung, denn nichts danach hängt davon ab eax. Oder Sie könnten einfach entscheiden, dass die Methode nur in den unteren 8 Bits einen Booleschen Wert zurückgibt und alle 3 Bytes spart!
Cody Grey

@ CodyGray In der Tat, vielen Dank :)
yoann

7

Gelee , 7 6 Bytes

Ḷæ«`i’

Probieren Sie es online!

Übernimmt die Eingabe als Befehlszeilenargument. Wenn eine Cullen-Zahl C ( n ) angegeben wird, wird n +1 ausgegeben (was in Jelly wahr ist, da es sich um eine Ganzzahl ungleich Null handelt. Beachten Sie, dass n ≥ 0 ist, da die Eingabe eine Ganzzahl ist und Cullen-Zahlen mit negativem n niemals Ganzzahlen sind.) . Wenn eine Nicht-Cullen-Zahl angegeben wird, wird 0 zurückgegeben, was in Jelly falsch ist.

Erläuterung

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

Bilden Sie im Grunde genommen ein Array von Cullen-Zahlen minus eins und suchen Sie dann darin nach der Eingabe minus eins. Wenn die Eingabe eine Cullen-Zahl ist, werden wir sie finden, andernfalls nicht. Beachten Sie, dass das Array unbedingt lang genug ist, um den Eingang zu erreichen, da C ( n ) immer größer als n ist .


7

JavaScript (ES6), 37-35 Byte

2 Bytes gespart dank Neil

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

Demo


Does x<n?f(n,k+1):x==nArbeit?
Neil

@Neil Das tut es sicher. :-)
Arnauld

Warum funktioniert ~ k, während k + 1 den Callstack überlastet?
Trlkly

Grundsätzlich undefined+1===NaNaber -~undefined===1. Sie können hier mehr über diese lesen .
Arnauld


3

Ohm , 8 Bytes

@Dº*≥Dlε

Probieren Sie es online!

           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 Bytes

ÝDo*¹<å

Probieren Sie es online!

Erläuterung:

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

Anonyme Funktion. Überprüft, ob xin der Folge C (n) für n in [0, x] generiert wird.

3 Bytes Golf von Giuseppe.

Probieren Sie es online!


Verwenden Sie x%in%...anstelle von any(x==...); Das werden Sie 4 Bytes fallen lassen
Giuseppe

Wenn ich dies also durch Ändern des Werts in " lapplyeinfach den Vektor prüfen" und "verwenden" scananstelle von Funktionsargumenten ändere, erhalte ich die Antwort von @giuseppe. Vielen Dank, dass Sie es separat veröffentlicht haben, damit ich sehen kann, was mir fehlt. Ich lerne mehr, indem ich selbst etwas versuche, auch wenn ich normalerweise verliere.
BLT

3

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

Aufgrund der Ähnlichkeiten zwischen all diesen Sprachen funktioniert dieser Code für jede Sprache

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

Ich werde die optimierte D-Version dieses Mal veröffentlichen, einige hübsche D-spezifische Tricks können verwendet werden.
Zacharý

Schlagen Sie i=30;i--;)if(i<<i==n-1)anstelle voni=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat 28.11.18



2

R , 26 Bytes

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

Probieren Sie es online!

Ein etwas anderer Ansatz als die andere R-Antwort ; liest aus stdinund da der Eingang garantiert zwischen 0 und 10 ^ 9 liegt, müssen wir nur nzwischen 0 und 26 prüfen .


Ich erinnere mich nie scan(). Gute Arbeit.
BLT

2

APL (Dyalog) , 9 Bytes

Um den Fall von n = 1 abzudecken , benötigt es⎕IO←0 was auf vielen Systemen Standard ist.

⊢∊1+⍳×2*⍳

Probieren Sie es online!

 [ist] n (das Argument)

 ein Mitglied von

1 eins

+ Plus

 die i ntegers 0 ... ( n - 1)

× mal

2 zwei

* hoch

 die i ntegers 0 ... ( n - 1)


"Standard auf vielen Systemen" bedeutet also, dass es nur existiert ?
Zacharý

@ Zacharý Ja, es wäre falsch, ⎕IO←0Nicht-Standard anzurufen , da viele es tatsächlich immer so eingestellt haben, ohne dass jedes Mal eine Angabe erforderlich ist.
Adám

Gut. Ich werde diesen Trick mit Sicherheit in MY anwenden (und MY kann nicht-0- und nicht-1-Indexursprünge haben), wenn ich jemals die Chance dazu bekomme.
Zacharý

@ Zacharý Wäre dafür nicht eine tatsächliche Installationsbasis / -versionen erforderlich, bei denen diese Werte Standard sind? ZB in SAX und ngn ⎕IO←0.
Adám

Ja, ich denke es würde. Und MY hat drei Iotas, also denke ich, dass das sowieso nicht verwendet werden würde.
Zacharý

2

Python 2 , 32 Bytes

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

Probieren Sie es online!

Erstellt eine Liste mit Cullen-Zahlen bis zu 10^9und zählt dann, wie oft die Eingabe darin erscheint. Vielen Dank an Vincent für den Hinweis, n<<n|1anstatt (n<<n)+12 Bytes zu sparen.


Sie können zwei Bytes mit n<<n|1( n<<ngerade) speichern ;)
Vincent

Dies schlägt fehl für 838860801. Sie brauchen range(26), weil das Sortiment nicht inklusive ist.
mbomb007

@ mbomb007 Danke. Ich habe dies für eine Weile getan und vergesse immer noch manchmal, dass Bereiche exklusiv für Rechte sind.
Xnor

2

D, 65 Bytes

Dies ist ein Port von @ HatsuPointerKuns Algorithmus zu D (das Original war bereits D-Code, aber dies ist mit D-spezifischen Tricks)

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

Wie? (D spezifische Tricks)

Das Vorlagensystem von D ist kürzer als das von C ++ und kann auf Typen schließen. Außerdem initialisiert D seine Variablen bei der Deklaration auf den Standardwert.


1

Mathematica, 30 Bytes

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

Reine Funktion, die eine nichtnegative Ganzzahl als Eingabe verwendet und Trueoder zurückgibt False. Wenn die Eingabe n, so (r=Range@#-1)setzt die Variable rzu sein {0, 1, ..., n-1}, und dann r2^r+1berechnet vektoriell die ersten nZahlen Cullen. MemberQ[...,#]prüft dann, ob nes sich um ein Element der Liste handelt.



1

Excel VBA, 45 Bytes

Anonyme VBE- [A1]Direktfensterfunktion, die Eingaben von Zellen und Ausgängen in das VBE-Direktfenster übernimmt

Muss in einem sauberen Modul ausgeführt werden oder Werte für i, j müssen zwischen den Durchläufen auf den Standardwert 0 zurückgesetzt werden

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

Input-Output

I / O wie im VBE-Direktfenster angezeigt

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

f(X)ist erfolgreich, wenn ein Wert I gefunden wird, bei dem X = I * 2 ^ I + 1 ist. Der Range-Hinweis verhindert, dass der Stack-Platz knapp wird, aber er reicht für den Bereich von Cullen-Zahlen bis 10 ^ 9 in der Frage-Spezifikation.

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

z.B

f(838860801).
true

1

cQuents , 9 Bytes

$0?1+$2^$

Probieren Sie es online!

Erläuterung

$0           n is 0-indexed
  ?          Mode query. Given input n, output true/false for if n is in the sequence.
   1+$2^$    Each item in the sequence equals `1+index*2^index`

1

TI-BASIC, 17 Bytes

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

Erläuterung

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

Vielleicht möchten Sie dem eine Erklärung hinzufügen.
Gryphon - Reinstate Monica

Fertig, danke für den Tipp.
calc84maniac

Das funktioniert, aber eine Erklärung von Befehl zu Befehl hilft normalerweise dabei, die meisten positiven Stimmen zu erzielen. Ich würde empfehlen, so etwas wie die Erklärung zu dieser Antwort zu machen . Ich weiß nicht, warum jemand Ihren Beitrag abgelehnt hat. Normalerweise ist es höflich, einen Kommentar zu hinterlassen, obwohl diese Idee oft ignoriert wird.
Gryphon - Reinstate Monica

Gern geschehen. Ich erinnere mich, als ich zum ersten Mal auf der Website war, haben mir die Leute solche Dinge erzählt. Nur den Gefallen weitergeben.
Gryphon - Reinstate Monica

0

QBIC , 24 Bytes

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

Erläuterung

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



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.