Sono un numero Cullen?


25

Un numero Cullen è qualsiasi numero contenuto nella sequenza generata utilizzando la formula:

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

Il tuo compito:

Scrivi un programma o una funzione che riceve un input e genera un valore di verità / falsa in base al fatto che l'input sia un numero Cullen.

Ingresso:

Un numero intero non negativo compreso tra 0 e 10 ^ 9 (incluso).

Produzione:

Un valore di verità / falsità che indica se l'input è un numero Cullen.

Casi test:

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

punteggio:

Questo è , quindi vince il punteggio più basso in byte.


1
Qual è l'intervallo di n ? In particolare, 1 è un numero Cullen?

3
@ ais523 secondo OEIS , lo è. nsembra essere basato su 0.
Steenbergh,

Giusto. Ho solo bisogno di sapere se la mia risposta di Jelly dovrebbe contenere o Rdentro :-)


Umm, che succede con il downvote?
Gryphon - Ripristina Monica il

Risposte:



16

codice macchina x86_64 ( System V ABI ), 28 27 byte

-1 byte grazie a @Cody Gray, grazie!

Un algoritmo a tempo costante!

_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

Spiegazione:

Lascia y un numero intero e x=y*2^y + 1. Prendendo tronchi, abbiamo y + log2(y) = log2(x-1), quindi y=log2(x-1)-log2(y). Ricollegando il valore di y, otteniamo y=log2(x-1)-log2(log2(x-1)-log2(y)). In questo modo ancora una volta, si ottiene: y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Rimuoviamo gli ultimi termini (dell'ordine di log2(log2(log2(log2(x)))), questo dovrebbe essere sicuro!), E supponiamo che x-1≈xotteniamo: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Ora, lasciando f(n) = floor(log2(n)), può essere verificato manualmente che ypuò essere esattamente recuperato da :,y=f(x)-f[f(x)-f(f(x))] per y <26 , e quindi x ⩽ 10 ^ 9 , come specificato dalla sfida (1) .

L'algoritmo consiste quindi semplicemente nel calcolare y dato x , e verificare che x == y * 2 ^ y + 1 . Il trucco è che f(n)può essere semplicemente implementato come bsristruzione (inversione bit-scan), che restituisce l'indice del primo 1 bit in n , e y*2^yas y << y.

Codice dettagliato:

_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) In effetti, questa uguaglianza sembra valere per valori fino a 50000 y .


4
Bene, sono abbastanza sicuro che questo si qualifichi come il codice più interessante per questa sfida finora. +1
Gryphon - Ripristina Monica il

1
Pre-XORing eaxti consentirebbe di eliminare il movzbl, risparmiando 1 byte. Avresti bisogno di fare lo XOR prima cmplche non ostruisca le bandiere, ovviamente, ma va bene perché non dipende da nulla eax. Oppure, potresti semplicemente decidere che il metodo restituisce un valore booleano solo negli 8 bit inferiori, salvando tutti e 3 i byte!
Cody Gray,

@CodyGray Infatti, grazie a lot :)
Yoann

7

Gelatina , 7 6 byte

Ḷæ«`i’

Provalo online!

Accetta input come argomento della riga di comando. Se viene dato un numero Cullen C ( n ), genera n +1 (che è vero in Jelly, essendo un numero intero diverso da zero; nota che abbiamo n ≥0 perché l'input è un numero intero, e i numeri Cullen con n negativo sono mai numeri interi) . Se viene assegnato un numero non Cullen, restituisce 0, che è false in Jelly.

Spiegazione

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

Fondamentalmente, forma una matrice di numeri Cullen meno uno, quindi cerca l'input meno uno al suo interno. Se l'input è un numero Cullen, lo troveremo, altrimenti non lo faremo. Si noti che l'array è necessariamente abbastanza lungo da raggiungere l'input, poiché C ( n ) è sempre maggiore di n .


7

JavaScript (ES6), 37 35 byte

Salvato 2 byte grazie a Neil

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

dimostrazione


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

@Neil Lo fa sicuramente. :-)
Arnauld il

Perché `~ k funziona, mentre k + 1 sovraccarica il callstack?
truscly

@trlkly Fondamentalmente, undefined+1===NaNma -~undefined===1. Puoi leggere di più su questo qui .
Arnauld,


3

Ohm , 8 byte

@Dº*≥Dlε

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

ÝDo*¹<å

Provalo online!

Spiegazione:

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

Funzione anonima. Controlla sex viene generato nella sequenza C (n) per n in [0, x].

3 byte giocati a golf da Giuseppe.

Provalo online!


usa x%in%...invece di any(x==...); che ti lascerà 4 byte
Giuseppe,

Quindi, se gioco questo cambiando lapplyin semplicemente controllando il vettore, e usando scaninvece di prendere argomenti di funzione - ottengo la risposta di @giuseppe. Grazie per averlo pubblicato separatamente in modo da poter vedere cosa mi manca - imparo di più provando qualcosa da solo, anche se di solito perdo.
BLT,

3

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

A causa delle somiglianze tra tutte queste lingue, questo codice funziona per ciascuna

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

Questa volta posterò la versione D ottimizzata, alcuni trucchi specifici per D possono essere utilizzati.
Zacharý,

Suggerisci i=30;i--;)if(i<<i==n-1)invece dii=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat il



2

R , 26 byte

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

Provalo online!

Un approccio leggermente diverso rispetto all'altra risposta R ; legge da stdine poiché l'ingresso è garantito tra 0 e 10 ^ 9, dobbiamo solo controllare ntra 0 e 26.


Non mi ricordo mai scan(). Buon lavoro.
BLT,

2

APL (Dyalog) , 9 byte

Per coprire il caso di n = 1, richiede ⎕IO←0quale sia l'impostazione predefinita su molti sistemi.

⊢∊1+⍳×2*⍳

Provalo online!

 [is] n (l'argomento)

 un membro di

1 uno

+ più

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

× volte

2 Due

* al potere di

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


Quindi, "impostazione predefinita su molti sistemi" significa che esiste ?
Zacharý,

@ Zacharý Sì, sarebbe sbagliato chiamare ⎕IO←0non standard, poiché molti lo hanno sempre impostato in questo modo, senza specifiche necessarie ogni volta.
Adám,

Bene. Utilizzerò sicuramente questo trucco in MY (e MY può avere origini dell'indice non 0 e non 1) se mai ne avrò la possibilità.
Zacharý,

@ Zacharý Non richiederebbe una base / versioni di installazione effettive in cui tali valori sono predefiniti? Ad esempio, in SAX e NGN, ⎕IO←0.
Adám,

Sì, suppongo che sarebbe. E il MIO ha tre iota, quindi penso che non verrebbero usati comunque.
Zacharý,

2

Python 2 , 32 byte

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

Provalo online!

Crea l'elenco di numeri Cullen fino a 10^9, quindi conta quante volte appare l'input in esso. Grazie a Vincent per aver sottolineato n<<n|1invece di (n<<n)+1aver salvato 2 byte.


Puoi salvare due byte usando n<<n|1( n<<nessere pari);)
Vincent,

Questo fallisce per 838860801. È necessario range(26), perché l'intervallo non è inclusivo.
mbomb007,

@ mbomb007 Grazie. L'ho fatto per un po 'e qualche volta dimentico ancora che le gamme sono esclusive.
xnor

2

D, 65 byte

Questa è una porta dell'algoritmo di @ HatsuPointerKun su D (l'originale era già codice D, ma questo è con trucchi specifici di D)

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

Come? (D trucchi specifici)

Il sistema di template di D è più corto di quello di C ++ e può inferire i tipi. E D inoltre inizializza le sue variabili al valore predefinito al momento della dichiarazione.


1

Mathematica, 30 byte

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

Funzione pura che accetta un intero non negativo come input e return Trueo False. Se l'input è n, quindi (r=Range@#-1)imposta la variabile rcome {0, 1, ..., n-1}, quindi r2^r+1calcola in modo vettoriale i primi nnumeri di Cullen. MemberQ[...,#]quindi controlla se nè un elemento dell'elenco.



1

Excel VBA, 45 byte

Funzione di finestra immediata VBE anonima che accetta input dalla cella [A1]e uscite alla finestra immediata di VBE

Deve essere eseguito in un modulo pulito o avere valori per i, j reimpostato sul valore predefinito 0 tra le esecuzioni

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

Input Output

I / O come si vede nella finestra immediata di 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 

1

Swi-Prolog, 69 byte

f(X)riesce se riesce a trovare un valore I dove X = I * 2 ^ I + 1. Il suggerimento intervallo lo interrompe a corto di spazio dello stack, ma è sufficiente per l'intervallo di numeri Cullen fino a 10 ^ 9 nelle specifiche della domanda.

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

per esempio

f(838860801).
true

1

cQuents , 9 byte

$0?1+$2^$

Provalo online!

Spiegazione

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

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

Spiegazione

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

Potresti voler aggiungere una spiegazione a questo.
Gryphon - Ripristina Monica il

Fatto, grazie per la punta.
calc84maniac

Funziona, ma una spiegazione comando per comando di solito aiuta a raccogliere la maggior parte dei voti. Consiglierei di fare qualcosa come la spiegazione su questa risposta . Non so perché qualcuno abbia retrocesso il tuo post. Di solito è cortesia comune lasciare un commento quando lo fai, anche se l'idea viene spesso ignorata.
Gryphon - Ripristina Monica il

Prego. Ricordo che quando mi sono iscritto al sito per la prima volta, le persone mi hanno raccontato questo tipo di cose. Sto solo trasmettendo il favore.
Gryphon - Ripristina Monica il

0

QBIC , 24 byte

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

Spiegazione

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

Provalo online. Verità è un array con un numero al suo interno: ,3o ,0eccetera. Falsey è un array vuoto: ()o !0dipende dal tuo interprete.



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.