Czy jestem numerem Cullen?

25

Liczba Cullen to dowolna liczba zawarta w sekwencji wygenerowanej za pomocą wzoru:

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

Twoje zadanie:

Napisz program lub funkcję, która odbiera dane wejściowe i wyświetla wartość prawda / fałsz na podstawie tego, czy dane wejściowe są liczbą Cullen.

Wkład:

Nieujemna liczba całkowita od 0 do 10 ^ 9 (włącznie).

Wydajność:

Wartość prawda / fałsz wskazująca, czy dane wejściowe są liczbą Cullen.

Przypadki testowe:

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

Punktacja:

To jest , więc wygrywa najniższy wynik w bajtach.

Gryphon - Przywróć Monikę
źródło
1
Jaki jest zakres n ? W szczególności, czy 1 jest liczbą Cullen?
3
@ ais523 według OEIS , tak jest. nwydaje się być oparty na 0.
steenbergh
Słusznie. R
2
Powiązane
DJMcMayhem
Umm, co jest z przegłosowaniem?
Gryphon - Przywróć Monikę

Odpowiedzi:

16

Kod maszynowy x86_64 ( System V ABI ), 28 27 bajtów

-1 bajt dzięki @Cody Gray, dzięki!

Algorytm stałego czasu!

_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

Wyjaśnienie:

Niech y jest liczbą całkowitą i x=y*2^y + 1. Mamy y + log2(y) = log2(x-1)więc dzienniki y=log2(x-1)-log2(y). Ponownie podając wartość y, otrzymujemy y=log2(x-1)-log2(log2(x-1)-log2(y)). Robi to jeszcze raz, otrzymujemy: y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Usuńmy ostatnie warunki (z rzędu log2(log2(log2(log2(x))))powinno to być bezpieczne!) I załóżmy x-1≈x, że otrzymujemy: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Teraz, pozwalając f(n) = floor(log2(n)), można zweryfikować ręcznie, że ymożna je dokładnie pobrać :,y=f(x)-f[f(x)-f(f(x))] dla y <26 , a zatem x ⩽ 10 ^ 9 , jak określono w wyzwaniu (1) .

Algorytm składa się po prostu z obliczenia y dla x i sprawdzenia, czy x == y * 2 ^ y + 1 . Sztuczka polega na tym, że f(n)można ją po prostu zaimplementować jako bsrinstrukcję (odwrócenie skanowania bitów), która zwraca indeks pierwszego 1-bitu w n , i y*2^yas y << y.

Szczegółowy kod:

_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) W rzeczywistości wydaje się, że ta równość obowiązuje dla wartości y do 50000.

yoann
źródło
4
Cóż, jestem prawie pewien, że kwalifikuje się jako najciekawszy jak dotąd kod tego wyzwania. +1
Gryphon - Przywróć Monikę
1
Pre-XORing eaxpozwoli Ci wyeliminować movzbloszczędzając 1 bajt. Trzeba by było zrobić XOR przed, cmplwięc nie będzie to oczywiście blokować flag, ale to jest całkowicie w porządku, ponieważ nic po tym nie zależy eax. Lub możesz po prostu zdecydować, że metoda zwraca wartość logiczną tylko w 8 niższych bitach, oszczędzając wszystkie 3 bajty!
Cody Gray
@CodyGray Rzeczywiście, wielkie dzięki :)
yoann
7

Galaretka , 7 6 bajtów

Ḷæ«`i’

Wypróbuj online!

Pobiera dane wejściowe jako argument wiersza polecenia. Jeśli podano liczbę Cullen C ( n ), wyprowadza n +1 (co jest prawdą w Jelly, która jest niezerową liczbą całkowitą; zwróć uwagę, że mamy n ≥0, ponieważ wejście jest liczbą całkowitą, a liczby Cullen z ujemną n nigdy nie są liczbami całkowitymi) . Jeśli podano liczbę inną niż Cullen, zwraca 0, co jest falsey w galaretce.

Wyjaśnienie

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

Zasadniczo utwórz tablicę liczb Cullena minus jeden, a następnie poszukaj danych wejściowych minus jeden. Jeśli dane wejściowe to liczba Cullena, znajdziemy je, w przeciwnym razie nie będziemy. Zauważ, że tablica musi być wystarczająco długa, aby dotrzeć do wejścia, ponieważ C ( n ) jest zawsze większe niż n .


źródło
7

JavaScript (ES6), 37 35 bajtów

Zaoszczędzono 2 bajty dzięki Neilowi

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

Próbny

Arnauld
źródło
Czy x<n?f(n,k+1):x==ndziała
Neil
@ Neil Z pewnością tak. :-)
Arnauld
Dlaczego `~ k działa, a k + 1 przeciąża stos wywołań?
trlkly
@trlkly Zasadniczo, undefined+1===NaNale -~undefined===1. Możesz przeczytać więcej na ten temat tutaj .
Arnauld
3

Ohm , 8 bajtów

@Dº*≥Dlε

Wypróbuj 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?
FrodCube
źródło
3

PHP , 43 bajty

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

Wypróbuj online!

Jörg Hülsermann
źródło
Czy $argnjest zmienna specjalna? Zmiana na $aoszczędziłaby 6 bajtów: tio.run
##
@topher Tak $argnjest dostępny, jeśli uruchamiasz PHP z wiersza poleceń z -Ropcją
Jörg Hülsermann
3

05AB1E , 7 bajtów

ÝDo*¹<å

Wypróbuj online!

Wyjaśnienie:

Ý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.
Towarzyszu SparklePony
źródło
3

R , 53 51 46 bajtów

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

Funkcja anonimowa. Sprawdza, czy xjest generowany w sekwencji C (n) dla nw [0, x].

3 bajty grał w golfa Giuseppe.

Wypróbuj online!

BLT
źródło
użyj x%in%...zamiast any(x==...); to zrzuci 4 bajty
Giuseppe
Jeśli więc przejdę do gry w golfa, zmieniając na lapplypo prostu sprawdzanie wektora i scanużyję zamiast brać argumenty funkcji - otrzymam odpowiedź @giuseppe. Dziękuję za opublikowanie go osobno, dzięki czemu mogę zobaczyć, czego mi brakuje - uczę się więcej, próbując czegoś na własną rękę, chociaż zazwyczaj przegrywam.
BLT
3

C, C ++, Java, C #, D: 70 bajtów

Ze względu na podobieństwa między tymi wszystkimi językami ten kod działa dla każdego z nich

int c(int n){for(int i=0;i<30;++i)if((1<<i)*i+1==n)return 1;return 0;}
HatsuPointerKun
źródło
Tym razem opublikuję zoptymalizowaną wersję D, można zastosować kilka całkiem specyficznych sztuczek D.
Zacharý
Zaproponuj i=30;i--;)if(i<<i==n-1)zamiasti=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat
2

R , 26 bajtów

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

Wypróbuj online!

Nieco inne podejście niż druga odpowiedź R ; odczytuje z, stdina ponieważ gwarantowane jest wejście od 0 do 10 ^ 9, musimy tylko sprawdzić nod 0 do 26.

Giuseppe
źródło
Nigdy nie pamiętać scan(). Dobra robota.
BLT
2

APL (Dyalog) , 9 bajtów

Aby objąć przypadek n = 1, wymaga ⎕IO←0domyślnej wartości w wielu systemach.

⊢∊1+⍳×2*⍳

Wypróbuj online!

 [is] n (argument)

 członek

1 jeden

+ plus

 z I ntegers 0 ... ( n -1)

× czasy

2 dwa

* do potęgi

 z I ntegers 0 ... ( n -1)

Adám
źródło
Zatem „domyślne w wielu systemach” oznacza, że ​​po prostu istnieje ?
Zacharý
@ Zacharý Tak, błędem byłoby nazywanie ⎕IO←0niestandardowych, ponieważ wielu z nich zawsze tak ustawia, bez konieczności każdorazowej specyfikacji.
Adám
Dobrze. Z pewnością skorzystam z tej sztuczki w MOIM (i MOJE mogą mieć początkowe indeksy inne niż 0 i inne niż 1), jeśli kiedykolwiek będę mieć taką możliwość.
Zacharý
@ Zacharý Czy nie wymagałoby to faktycznej instalacji / wersji, w których te wartości są domyślne? Np SAX i NGN, ⎕IO←0.
Adám,
Tak, chyba tak. I MOJE ma trzy joty, więc myślę, że i tak by nie zostało użyte.
Zacharý
2

Python 2 , 32 bajty

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

Wypróbuj online!

Tworzy listę liczb Cullen do 10^9, a następnie zlicza, ile razy pojawia się na niej dane wejściowe. Dzięki Vincent za wskazanie n<<n|1zamiast (n<<n)+1oszczędzania 2 bajtów.

xnor
źródło
Możesz zapisać dwa bajty używając n<<n|1( n<<nbędąc parzystym);)
Vincent
To się nie udaje 838860801. Potrzebujesz range(26), ponieważ zakres nie obejmuje.
mbomb007
@ mbomb007 Thanks. Robiłem to przez jakiś czas i wciąż czasami zapominam, że zakresy są wykluczające.
xnor
2

D, 65 bajtów

Jest to port algorytmu @ HatsuPointerKun do D (oryginał był już kodem D, ale dotyczy to sztuczek specyficznych dla D)

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

W jaki sposób? (D określone triki)

System szablonów D jest krótszy niż C ++ i może wnioskować o typach. Po deklaracji D inicjuje również zmienne do wartości domyślnych.

Zacharý
źródło
1

Mathematica, 30 bajtów

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

Czysta funkcja przyjmująca nieujemną liczbę całkowitą jako dane wejściowe i zwracające Truelub False. Jeśli dane wejściowe są n, to (r=Range@#-1)ustawia zmienną rna {0, 1, ..., n-1}, a następnie r2^r+1oblicza wektorowo pierwsze nliczby Cullen. MemberQ[...,#]następnie sprawdza, czy njest elementem listy.

Greg Martin
źródło
1

Mathematica, 32 bajty

!Table[x*2^x+1,{x,0,#}]~FreeQ~#&
J42161217
źródło
1

Excel VBA, 45 bajtów

Anonimowa funkcja bezpośredniego okna VBE, która przenosi dane wejściowe z komórki [A1]i wysyła dane do bezpośredniego okna VBE

Musi być uruchamiany w czystym module lub mieć wartości dla i, j być resetowany do wartości domyślnej 0 między przebiegami

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

Wejście wyjście

I / O jak widać w bezpośrednim oknie 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 
Taylor Scott
źródło
1

Swi-Prolog, 69 bajtów

f(X)powiedzie się, jeśli może znaleźć wartość I, gdzie X = I * 2 ^ I + 1. Wskazówka zakresu powstrzymuje go przed wyczerpaniem miejsca na stosie, ale wystarcza dla zakresu liczb Cullen do 10 ^ 9 w specyfikacji pytania.

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

na przykład

f(838860801).
true
TessellatingHeckler
źródło
1

cQuents , 9 bajtów

$0?1+$2^$

Wypróbuj online!

Wyjaśnienie

$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`
Stephen
źródło
1

TI-BASIC, 17 bajtów

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

Wyjaśnienie

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
źródło
Możesz dodać do tego wyjaśnienie.
Gryphon - Przywróć Monikę
Gotowe, dziękuję za wskazówkę.
calc84maniac
To działa, ale wyjaśnienie polecenia po poleceniu zwykle pomaga zdobyć większość pozytywnych opinii. Poleciłbym zrobić coś w rodzaju wyjaśnienia tej odpowiedzi . Nie wiem jednak, dlaczego ktoś ocenił twój post. Zazwyczaj pozostawienie komentarza jest zazwyczaj uprzejme, chociaż pomysł ten jest często ignorowany.
Gryphon - Przywróć Monikę
Proszę bardzo. Pamiętam, kiedy po raz pierwszy dołączyłem do strony, ludzie mówili mi tego typu rzeczy. Przekazuję tylko przysługę.
Gryphon - Przywróć Monikę
0

QBIC , 24 bajty

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

Wyjaśnienie

[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.
Steenbergh
źródło
0

k , 19 bajtów

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

Wypróbuj online. Prawda jest tablicą z liczbą: ,3lub ,0et cetera. Falsey jest pustą tablicą: ()lub w !0zależności od tłumacza.

zgrep
źródło