Eu sou um número Cullen?


25

Um número Cullen é qualquer número que esteja contido na sequência gerada usando a fórmula:

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

Sua tarefa:

Escreva um programa ou função que receba uma entrada e emita um valor de verdade / falsidade com base no fato de a entrada ser um número Cullen.

Entrada:

Um número inteiro não negativo entre 0 e 10 ^ 9 (inclusive).

Saída:

Um valor de verdade / falsidade que indica se a entrada é um número Cullen.

Casos de teste:

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

Pontuação:

Isso é , então a pontuação mais baixa em bytes vence.


1
Qual é o alcance de n ? Em particular, 1 é um número Cullen?

3
@ ais523 de acordo com a OEIS , é. nparece ser baseado em 0.
steenbergh

Justo. Só precisava saber se a minha resposta Jelly deve ter uma ou Rnele :-)


Umm, o que há com o voto negativo?
Gryphon - Restabelece Monica

Respostas:



16

código de máquina x86_64 ( ABI do sistema V ), 28 27 bytes

-1 byte graças a @Cody Gray, obrigado!

Um algoritmo de tempo 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

Explicação:

Seja y um número inteiro e x=y*2^y + 1. Tomando logs, temos y + log2(y) = log2(x-1), assim y=log2(x-1)-log2(y). Conectando de volta o valor de y, obtemos y=log2(x-1)-log2(log2(x-1)-log2(y)). Fazendo isso mais uma vez, obtém-se: y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Vamos remover os últimos termos (da ordem de log2(log2(log2(log2(x)))), isso deve ser seguro!) E supor que x-1≈x, obtemos: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Agora, deixando f(n) = floor(log2(n)), pode ser verificado manualmente que ypode ser recuperado exatamente por:, y=f(x)-f[f(x)-f(f(x))]para y <26 e, portanto, x ⩽ 10 ^ 9 , conforme especificado pelo desafio (1) .

O algoritmo consiste simplesmente em calcular y dado x e verificar se x == y * 2 ^ y + 1 . O truque é que f(n)pode ser simplesmente implementado como a bsrinstrução (reversão de verificação de bits), que retorna o índice do primeiro bit de 1 em n e y*2^ycomo y << y.

Código detalhado:

_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 fato, essa igualdade parece valer para valores de y até 50000.


4
Bem, eu tenho certeza que esse é o código mais interessante para esse desafio até agora. +1
Gryphon - Restabelecer Monica

1
O pré-XORing eaxpermitiria eliminar o movzblbyte de economia de 1 byte. Você precisaria fazer o XOR antes do XOR, cmplpara que ele não derrube as bandeiras, é claro, mas tudo bem, porque nada depois disso depende eax. Ou, você pode simplesmente decidir que o método retornará um Booleano apenas nos 8 bits inferiores, salvando todos os 3 bytes!
Cody Grey

@CodyGray Na verdade, muito obrigado :)
yoann

7

Geléia , 7 6 bytes

Ḷæ«`i’

Experimente online!

Recebe entrada como um argumento de linha de comando. Se dado um número Cullen C ( n ), gera n +1 (que é verdadeiro em Jelly, sendo um número inteiro diferente de zero; observe que temos n ≥0 porque a entrada é um número inteiro e os números Cullen com n negativo nunca são inteiros) . Se for fornecido um número que não seja Cullen, retornará 0, que é falsey em Jelly.

Explicação

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

Basicamente, forme uma matriz de números Cullen menos um, depois procure a entrada menos um. Se a entrada for um número Cullen, nós a encontraremos, caso contrário, não. Observe que a matriz é necessariamente longa o suficiente para alcançar a entrada, porque C ( n ) é sempre maior que n .


7

JavaScript (ES6), 37 35 bytes

Economizou 2 bytes graças a Neil

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

Demo


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

@ Neil Com certeza faz. :-)
Arnauld

Por que `~ k funciona, enquanto k + 1 sobrecarrega o pilha de chamadas?
trlkly

@trlkly Basicamente, undefined+1===NaNmas -~undefined===1. Você pode ler mais sobre isso aqui .
Arnauld


3

Ohm , 8 bytes

@Dº*≥Dlε

Experimente 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*¹<å

Experimente online!

Explicação:

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

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

Função anônima. Verifica se xé gerado na sequência C (n) por n em [0, x].

3 bytes jogados por Giuseppe.

Experimente online!


use em x%in%...vez de any(x==...); isso deixará você com 4 bytes
Giuseppe

Portanto, se eu jogar isso alterando lapplysimplesmente para verificar o vetor e usar em scanvez de usar argumentos de função - recebo a resposta do @giuseppe. Obrigado por publicá-lo separadamente, para que eu possa ver o que estou perdendo - eu aprendo mais tentando algo sozinho, mesmo que geralmente perco.
BLT

3

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

Devido às semelhanças entre todos esses idiomas, esse 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;}

Vou postar a versão D otimizada desta vez, alguns truques bem específicos de D podem ser usados.
Zacharý

Sugerir em i=30;i--;)if(i<<i==n-1)vez dei=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat 28/11



2

R , 26 bytes

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

Experimente online!

Uma abordagem ligeiramente diferente da outra resposta R ; lê stdine desde que a entrada é garantida entre 0 e 10 ^ 9, basta verificar nentre 0 e 26.


Eu nunca me lembro scan(). Bom trabalho.
BLT

2

APL (Dyalog) , 9 bytes

Para cobrir o caso de n = 1, requer ⎕IO←0qual é o padrão em muitos sistemas.

⊢∊1+⍳×2*⍳

Experimente online!

 [is] n (o argumento)

 um membro de

1 1

+ mais

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

× vezes

2 dois

* ao poder de

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


Então, "padrão em muitos sistemas" significa que simplesmente existe ?
Zacharý

@ Zacharý Sim, seria errado chamar ⎕IO←0não-padrão, pois muitos de fato sempre o definem assim, sem nenhuma especificação necessária a cada vez.
Adám 04/08/19

Bem. Vou usar esse truque no MY com certeza (e o MY pode ter origens de índice diferentes de 0 e não 1) se eu tiver a chance.
Zacharý 4/08/19

@ Zacharý Isso não exigiria uma base / versões de instalação reais em que esses valores sejam padrão? Por exemplo, em SAX e ngn ⎕IO←0,.
Adám 5/08/17

Sim, acho que sim. E o MY tem três cotas, então acho que não seria usado de qualquer maneira.
Zacharý 5/08

2

Python 2 , 32 bytes

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

Experimente online!

Cria a lista de números de Cullen até 10^9e conta quantas vezes a entrada aparece nela. Obrigado a Vincent por apontar, em n<<n|1vez de (n<<n)+1, salvar 2 bytes.


Você pode salvar dois bytes usando n<<n|1( n<<nsendo mesmo);)
Vincent

Isso falha para 838860801. Você precisa range(26), porque o intervalo não é inclusivo.
mbomb007

@ mbomb007 Obrigado. Fiz isso por um tempo e, às vezes, ainda esqueço que os intervalos são exclusivos.
xnor

2

D, 65 bytes

Esta é uma porta do algoritmo de @ HatsuPointerKun para D (o original já era código D, mas isso é com truques 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;}

Quão? (D truques específicos)

O sistema de modelos de D é mais curto que o de C ++ e pode inferir tipos. E D também inicializa suas variáveis ​​para o padrão na declaração.


1

Mathematica, 30 bytes

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

Função pura, recebendo um número inteiro não negativo como entrada e retornando Trueou False. Se a entrada for n, (r=Range@#-1)defina a variável rcomo sendo {0, 1, ..., n-1}e r2^r+1calcula vetorialmente os primeiros nnúmeros de Cullen. MemberQ[...,#]depois verifica se né um elemento da lista.



1

Excel VBA, 45 bytes

Função de janela imediata do VBE anônima que leva a entrada da célula [A1]e sai para a janela imediata do VBE

Deve ser executado em um módulo limpo ou ter valores para i, j ser redefinido para o valor padrão de 0 entre execuções

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

Entrada / Saída

E / S como visto na janela imediata do 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 bytes

f(X)obtém êxito se puder encontrar um valor I em que X = I * 2 ^ I + 1. A dica de intervalo impede que fique sem espaço na pilha, mas é suficiente para o intervalo de números de Cullen de até 10 ^ 9 na especificação da pergunta.

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

por exemplo

f(838860801).
true

1

cQuents , 9 bytes

$0?1+$2^$

Experimente online!

Explicação

$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

Explicação

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

Você pode querer adicionar uma explicação para isso.
Gryphon - Restabelece Monica

Feito, obrigado pela dica.
calc84maniac

Isso funciona, mas uma explicação de comando por comando geralmente ajuda a reunir a maioria dos votos positivos. Eu recomendaria fazer algo parecido com a explicação sobre esta resposta . Não sei por que alguém votou negativamente no seu post. Geralmente, é uma cortesia comum deixar um comentário quando você faz isso, embora essa ideia seja frequentemente ignorada.
Gryphon - Restabelece Monica

Não há de quê. Lembro que, quando entrei no site, as pessoas me contaram esse tipo de coisa. Apenas passando o favor.
Gryphon - Restabelece Monica

0

QBIC , 24 bytes

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

Explicação

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

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

Experimente online. Truthy é uma matriz com um número: ,3or ,0eteter. Falsey é uma matriz vazia: ()ou !0dependendo do seu intérprete.



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.