¿Soy un número Cullen?

25

Un número de Cullen es cualquier número que está contenido en la secuencia generada usando la fórmula:

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

Tu tarea:

Escriba un programa o función que reciba una entrada y genere un valor verdadero / falso basado en si la entrada es un Número Cullen.

Entrada:

Un entero no negativo entre 0 y 10 ^ 9 (inclusive).

Salida:

Un valor verdadero / falso que indica si la entrada es un número Cullen.

Casos de prueba:

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

Tanteo:

Este es el , por lo que gana la puntuación más baja en bytes.

Gryphon - Restablece a Monica
fuente
1
¿Cuál es el rango de n ? En particular, ¿es 1 un número de Cullen?
3
@ ais523 según OEIS , lo es. nParece estar basado en 0.
steenbergh
Lo suficientemente justo. Solo necesitaba saber si mi respuesta Jelly debería tener un o R:-)
2
Relacionado
DJMcMayhem
Umm, ¿qué pasa con el voto negativo?
Gryphon - Restablece a Monica el

Respuestas:

16

Código de máquina x86_64 ( System V ABI ), 28 27 bytes

-1 byte gracias a @Cody Gray, ¡gracias!

¡Un algoritmo de tiempo constante!

_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

Explicación:

Deje y un número entero y x=y*2^y + 1. Tomando registros, tenemos y + log2(y) = log2(x-1), por lo tanto y=log2(x-1)-log2(y). Volviendo a conectar el valor de y, obtenemos y=log2(x-1)-log2(log2(x-1)-log2(y)). Hacer esto una vez más, se obtiene: y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Eliminemos los últimos términos (del orden de log2(log2(log2(log2(x)))), ¡esto debería ser seguro!), Y supongamos que x-1≈xobtenemos: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Ahora, dejando f(n) = floor(log2(n)), se puede verificar manualmente que yse puede recuperar exactamente por:, y=f(x)-f[f(x)-f(f(x))]para y <26 , y por lo tanto x ⩽ 10 ^ 9 , como se especifica en el desafío (1) .

El algoritmo simplemente consiste en calcular y dado x , y verificar que x == y * 2 ^ y + 1 . El truco es que f(n)simplemente se puede implementar como la bsrinstrucción (exploración de bits inversa), que devuelve el índice del primer 1 bit en n , y y*2^ycomo y << y.

Código detallado:

_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) De hecho, esta igualdad parece mantenerse para valores de y hasta 50000.

yoann
fuente
44
Bueno, estoy bastante seguro de que esto califica como el código más interesante para este desafío hasta ahora. +1
Gryphon - Restablece a Monica el
1
Pre-XORing eaxle permitiría eliminar el movzbl, ahorrando 1 byte. Tendría que hacer el XOR antes del cmplpara que no golpee las banderas, por supuesto, pero eso está muy bien porque nada de eso depende eax. O bien, podría decidir que el método devuelve un valor booleano solo en los 8 bits inferiores, ¡guardando los 3 bytes!
Cody Gray
@CodyGray De hecho, muchas gracias :)
yoann
7

Gelatina , 7 6 bytes

Ḷæ«`i’

Pruébalo en línea!

Toma entrada como un argumento de línea de comando. Si se le da un número de Cullen C ( n ), genera n +1 (que es verdad en Jelly, siendo un número entero distinto de cero; tenga en cuenta que tenemos n ≥0 porque la entrada es un número entero, y los números de Cullen con n negativo nunca son números enteros) . Si se le da un número que no es Cullen, devuelve 0, que es falsey en Jelly.

Explicación

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

Básicamente, forma una matriz de números de Cullen menos uno, luego busca la entrada menos uno. Si la entrada es un número de Cullen, lo encontraremos, de lo contrario no lo haremos. Tenga en cuenta que la matriz es necesariamente lo suficientemente larga como para llegar a la entrada, porque C ( n ) siempre es mayor que n .


fuente
7

JavaScript (ES6), 37 35 bytes

Guardado 2 bytes gracias a Neil

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

Manifestación

Arnauld
fuente
Funciona x<n?f(n,k+1):x==n?
Neil
@Neil Seguro que sí. :-)
Arnauld
¿Por qué funciona `~ k, mientras que k + 1 sobrecarga la pila de llamadas?
Trlyly
@trlkly Básicamente, undefined+1===NaNpero -~undefined===1. Puedes leer más sobre esto aquí .
Arnauld
3

Ohm , 8 bytes

@Dº*≥Dlε

Pruébalo en línea!

           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
fuente
3

05AB1E , 7 bytes

ÝDo*¹<å

Pruébalo en línea!

Explicación:

Ý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.
Camarada SparklePony
fuente
3

R , 53 51 46 bytes

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

Función anónima. Comprueba si xse genera en la secuencia C (n) para n en [0, x].

3 bytes de golf de Giuseppe.

Pruébalo en línea!

BLT
fuente
usar en x%in%...lugar de any(x==...); eso te dejará 4 bytes
Giuseppe
Entonces, si juego esto cambiando lapplyal simplemente verificar el vector y usarlo en scanlugar de tomar argumentos de función, obtengo la respuesta de @giuseppe. Gracias por publicarlo por separado para que pueda ver lo que me falta: aprendo más probando algo por mi cuenta, aunque generalmente pierdo.
BLT
3

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

Debido a las similitudes entre todos estos idiomas, este código funciona para cada

int c(int n){for(int i=0;i<30;++i)if((1<<i)*i+1==n)return 1;return 0;}
HatsuPointerKun
fuente
Publicaré la versión D optimizada esta vez, se pueden usar algunos trucos bastante específicos de D.
Zacharý
Sugerir en i=30;i--;)if(i<<i==n-1)lugar dei=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat
2

R , 26 bytes

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

Pruébalo en línea!

Un enfoque ligeramente diferente que la otra respuesta R ; lee desde stdiny dado que la entrada está garantizada entre 0 y 10 ^ 9, solo tenemos que verificar nentre 0 y 26.

Giuseppe
fuente
Nunca recuerdo scan(). Buen trabajo.
BLT
2

APL (Dyalog) , 9 bytes

Para cubrir el caso de n = 1, requiere ⎕IO←0cuál es el valor predeterminado en muchos sistemas.

⊢∊1+⍳×2*⍳

Pruébalo en línea!

 [es] n (el argumento)

 un miembro de

1 uno

+ más

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

× veces

2 dos

* al poder de

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

Adán
fuente
Entonces, ¿"predeterminado en muchos sistemas" significa que simplemente existe ?
Zacharý
@ Zacharý Sí, sería un error llamar ⎕IO←0no estándar, ya que muchos siempre lo tienen configurado así, sin necesidad de especificarlo cada vez.
Adám
Bien. Voy a usar ese truco en MY con seguridad (y MY puede tener orígenes de índice no 0 y no 1) si alguna vez tengo la oportunidad de hacerlo.
Zacharý
@ Zacharý ¿No requeriría eso una base de instalación real / versiones donde esos valores son predeterminados? Por ejemplo, en SAX y NGN, ⎕IO←0.
Adám
Sí, supongo que sí. Y MY tiene tres iotas, así que creo que de todos modos no se usaría.
Zacharý
2

Python 2 , 32 bytes

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

Pruébalo en línea!

Crea la lista de números de Cullen hasta 10^9, luego cuenta cuántas veces aparece la entrada en ella. Gracias a Vincent por señalar en n<<n|1lugar de (n<<n)+1guardar 2 bytes.

xnor
fuente
Puede guardar dos bytes usando n<<n|1( n<<nsiendo par);)
Vincent
Esto falla por 838860801. Necesitas range(26), porque el rango no es inclusivo.
mbomb007
@ mbomb007 Gracias. Lo he hecho por un tiempo y todavía a veces olvido que los rangos son exclusivos.
xnor
2

D, 65 bytes

Este es un puerto del algoritmo de @ HatsuPointerKun a D (el original ya era código D, pero esto es con trucos específicos de D)

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

¿Cómo? (D trucos específicos)

El sistema de plantillas de D es más corto que el de C ++ y puede inferir tipos. Y D también inicializa sus variables al valor predeterminado tras la declaración.

Zacharý
fuente
1

Mathematica, 30 bytes

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

Función pura que toma un entero no negativo como entrada y regresa Trueo False. Si la entrada es n, (r=Range@#-1)establece la variable rpara que sea {0, 1, ..., n-1}, y luego r2^r+1computa vectorialmente los primeros nnúmeros de Cullen. MemberQ[...,#]luego verifica si nes un elemento de la lista.

Greg Martin
fuente
1

Mathematica, 32 bytes

!Table[x*2^x+1,{x,0,#}]~FreeQ~#&
J42161217
fuente
1

Excel VBA, 45 bytes

Función de ventana inmediata anónima de VBE que toma la entrada de la celda [A1]y las salidas a la ventana inmediata de VBE

Debe ejecutarse en un módulo limpio o tener valores para i, j restablecerse al valor predeterminado de 0 entre ejecuciones

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

De entrada y salida

E / S como se ve en la ventana inmediata de 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
fuente
1

Swi-Prolog, 69 bytes

f(X)tiene éxito si puede encontrar un valor I donde X = I * 2 ^ I + 1. La sugerencia de rango evita que se quede sin espacio de pila, pero es suficiente para el rango de números de Cullen hasta 10 ^ 9 en la especificación de la pregunta.

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

p.ej

f(838860801).
true
TessellatingHeckler
fuente
1

cQuents , 9 bytes

$0?1+$2^$

Pruébalo en línea!

Explicación

$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
fuente
1

TI-BASIC, 17 bytes

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

Explicación

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
fuente
Es posible que desee agregar una explicación a esto.
Gryphon - Restablece a Mónica el
Hecho, gracias por el consejo.
calc84maniac
Eso funciona, pero una explicación de comando por comando generalmente ayuda a obtener la mayoría de los votos. Recomiendo hacer algo como la explicación de esta respuesta . Sin embargo, no sé por qué alguien rechazó tu publicación. Por lo general, es cortesía dejar un comentario cuando lo haces, aunque esa idea a menudo se ignora.
Gryphon - Restablece a Mónica el
De nada. Recuerdo que cuando me uní al sitio por primera vez, la gente me contaba este tipo de cosas. Solo pasando el favor.
Gryphon - Restablece a Mónica el
0

QBIC , 24 bytes

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

Explicación

[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
fuente
0

k , 19 bytes

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

Pruébalo en línea. La verdad es una matriz con un número: ,3o ,0etcétera. Falsey es una matriz vacía: ()o !0depende de su intérprete.

zgrep
fuente