Um número de Proth , nomeado após François Proth, é um número que pode ser expresso como
N = k * 2^n + 1
Onde k
é um número inteiro positivo ímpar e n
é um número inteiro positivo tal que 2^n > k
. Vamos usar um exemplo mais concreto. A Tomada 3. 3 é um número de Proth porque pode ser escrito como
(1 * 2^1) + 1
e 2^1 > 1
está satisfeito. 5 Também é um número de Proth porque pode ser escrito como
(1 * 2^2) + 1
e 2^2 > 1
está satisfeito. No entanto, 7 não é um número de Proth porque a única maneira de escrevê-lo no formulário N = k * 2^n + 1
é
(3 * 2^1) + 1
e 2^1 > 3
não está satisfeito.
Seu desafio é bastante simples: você deve escrever um programa ou função que, dado um número inteiro positivo, determine se é ou não um número Proth. Você pode receber entradas em qualquer formato razoável e deve gerar um valor verdadeiro, se for um número Proth, e um valor falso, se não for. Se o seu idioma tiver funções de "detecção de número de próstata", você poderá usá-las.
Teste de E / S
Aqui estão os primeiros 46 números Proth de até 1000. ( A080075 )
3, 5, 9, 13, 17, 25, 33, 41, 49, 57, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225, 241, 257, 289, 321, 353, 385, 417, 449, 481, 513, 545, 577, 609, 641, 673, 705, 737, 769, 801, 833, 865, 897, 929, 961, 993
Qualquer outra entrada válida deve fornecer um valor falso.
Como de costume, isso é código-golfe, então as brechas padrão se aplicam e a resposta mais curta em bytes vence!
Teoria dos números - nota de lado divertida:
O maior primo conhecido que não é um primo de Mersenne é o 19249 * 2^13018586 + 1
que, por acaso, também é um número de Proth!
fonte
Python, 22 bytes
Esta é uma porta da minha resposta Jelly . Teste em Ideone .
Como funciona
Seja j um número inteiro estritamente positivo. j + 1 alterna todos os bits finais de j e o bit não definido adjacente. Por exemplo, 10011 2 + 1 = 10100 2 .
Como ~ j = - (j + 1) = -j - 1 , -j = ~ j + 1 , então -n aplica o acima ao NOT bit a bit de j (que alterna todos os bits), alternando todos os bits antes do último 1 .
Ao pegar j & -j - AND bit a bit de j e -j - todos os bits antes e depois do último bit definido são anulados (desde que desiguais em j e -j ), produzindo assim a potência mais alta de 2 que divide j uniformemente.
Para a entrada N , queremos aplicar o acima a N-1 para encontrar 2 n , a potência mais alta de 2 que divide N-1 . Se m = N - 1 , -m = - (N - 1) = 1 - N , então (N - 1) & (1 - N) produz 2 n .
Tudo o que resta a testar é se 2 n > k . Se k> 0 , isto é verdadeiro se e só se (2 N ) 2 > K2 n , o que é verdade em si, se e somente se (2 N ) 2 ≥ K2 n + 1 = N .
Finalmente, se (2 n ) 2 = N = k2 n + 1 , 2 n deve ser ímpar ( 1 ) para que as paridades de ambos os lados possam corresponder, implicando que k = 0 e N = 1 . Neste caso (N - 1) & (1 - N) = 0 & 0 = 0 e ((N - 1) & (1 - N)) 2 = 0 <1 = N .
Portanto, ((N - 1) e (1 - N)) 2 > N é verdadeiro se e somente se N for um número Proth.
Ignorando imprecisões de ponto flutuante, isso é equivalente ao código
N-1&1-N>N**.5
na implementação.fonte
Python 2, 23 bytes
fonte
Mathematica,
5048454038353129 bytesO Mathematica geralmente é péssimo quando se trata de código de golfe, mas às vezes há um recurso interno que faz as coisas parecerem realmente boas.
Um teste:
Edit: Na verdade, se eu roubar a idéia AND de bit a bit de Dennis , posso reduzi-lo para
232220 bytes.Mathematica,
232220 bytes (obrigado A Simmons )fonte
g=
, uma função pura é boa!Select[Range@1000,f]
.05AB1E ,
1410 bytesAgradecimentos a Emigna por salvar 4 bytes!
Código:
Usa a codificação CP-1252 . Experimente online! .
Explicação:
Para a explicação, vamos usar o número 241 . Primeiro decrementamos o número por um com
<
. Isso resulta em 240 . Agora, calculamos os fatores primos (com duplicatas) usandoÒ
. Os principais fatores são:Nós os dividimos em duas partes. Usando
2Q·0K
, obtemos a lista de dois:Com
®2K
, obtemos a lista dos números restantes:Finalmente, pegue o produto de ambos.
[2, 2, 2, 2]
resulta em 16 . O produto dos[3, 5]
resultados em 15 .Este caso de teste é verdadeiro desde 16 > 15 .
fonte
<©Ó¬oD®s/›
ou<DÓ0èoDŠ/›
para 10.Brain-Flak ,
460350270266264188176 bytesExperimente online!
Explicação
O programa passa por potências de dois e quatro até encontrar uma potência de dois maior que N-1. Quando encontra, verifica a divisibilidade de N-1 pela potência de dois usando o módulo e gera o resultado
Este programa não está limpo de pilha. Se você adicionar 4 bytes extras, poderá fazer com que a pilha fique limpa:
fonte
MATL , 9 bytes
A verdade é a saída
1
. Falsy é0
ou saída vazia. (As únicas entradas que produzem saída vazia são1
e2
; o restante produz uma0
ou outra1
).Experimente online!
Explicação
Deixe x denotar a entrada. Seja y a maior potência de 2 que divide x −1, e z = ( x −1) / y . Observe que z é automaticamente ímpar. Então x é um número Proth se e somente se y > z , ou equivalente se y 2 > x −1.
fonte
Braquilog , 28 bytes
Experimente online!
Verifique todos os casos de teste de uma só vez. (Ligeiramente modificado.)
Explicação
Brachylog, sendo um derivado do Prolog, é muito bom em provar coisas.
Aqui, provamos o seguinte:
fonte
Haskell,
5546 bytesEdit: Graças a nimi, agora 46 bytes
fonte
sum[1| ... ]
. Aqui podemos ir mais longe e mover o teste de igualdade em frente ao|
e verificar comor
se algum deles é verdadeiro:f x=or[k*2^n+1==x|k<-...,n<-...,2^n>k]
.ECMAScript Regex,
484341 bytesAs expressões regulares de Neil e H.PWiz (ambas também com sabor ECMAScript) são bonitas por si só. Há outra maneira de fazê-lo, que por uma coincidência bastante elegante era 1 byte a mais do que o de Neil, e agora com o golfe sugerido por H.PWiz (obrigado!), É 1 byte a
maismenos de H.PWiz de.Aviso: apesar do tamanho pequeno desse regex, ele contém um grande spoiler . Eu recomendo aprender como resolver problemas matemáticos unários na expressão regular ECMAScript, descobrindo os insights matemáticos iniciais de forma independente. Foi uma jornada fascinante para mim, e não quero estragá-la para quem potencialmente queira experimentá-la, especialmente aqueles com interesse em teoria dos números. Consulte esta postagem anterior para obter uma lista de problemas recomendados consecutivamente identificados por spoilers para resolver um por um.
Portanto , não leia mais se não quiser que você estrague uma mágica avançada de expressões regulares unárias . Se você quiser tentar descobrir essa mágica, recomendo começar resolvendo alguns problemas no regex ECMAScript, conforme descrito no post acima.
Portanto, esse regex funciona de maneira bem simples: começa subtraindo um. Então encontra o maior fator ímpar, k . Em seguida, dividimos por k (usando o algoritmo de divisão explicado brevemente em um parágrafo com etiqueta de spoiler do meu número de referência do fatorial ). Sorrateiramente, fazemos uma afirmação simultânea de que o quociente resultante é maior que k . Se a divisão corresponder, temos um número Proth; se não, nós não.
Consegui eliminar 2 bytes desse regex (43 → 41) usando um truque encontrado por Grimy que pode reduzir ainda mais a divisão no caso de garantir que o quociente seja maior ou igual ao divisor.
Experimente online!
fonte
Julia, 16 bytes
Créditos ao @Dennis pela resposta e algumas dicas de golfe!
fonte
&
tem a mesma precedência que*
.-~-x
vez de(1-x)
. Além disso, há em√x
vez dex^.5
, mas ele não salva bytes.R,
5250 bytesO programa começa dividindo
N-1
(chamado aquiP
ex
) pelo2
maior tempo possível para encontrar a2^n
parte da equação, deixandok=(N-1)/2^n
e depois calcular sek
é ou não inferior a2^n
, usando o fato de que2^n>x/2^n <=> (2^n)²>x <=> 2^2n>x
fonte
P=
no início e mudar o final para2^n>x
e salvar como 5 ou 6 bytesRegex (ECMAScript),
4038 bytes-2 bytes graças ao Deadcode
Experimente online!
Versão comentada:
fonte
^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$)
( Experimente online )J, 10 bytes
Baseado na solução bit a bit do @Dennis .
Recebe uma entrada
n
e retorna 1 se for o número Proth mais 0.Uso
Explicação
fonte
AND
. legal!Retina 0.8.2 , 47 bytes
Experimente online! Explicação: Dado um número Prothk ⋅ 2n+ 1 , você pode derivar dois novos números Proth ( 2 k ± 1 ) ⋅ 2n + 1+ 1 . Podemos executar isso ao contrário até obtermos um número Proth em quek = 1 . Isso é facilmente realizado através da transformação da representação binária.
Converta para unário.
Converta em binário.
Execute repetidamente a fórmula de geração Proth ao contrário.
Combine o caso base da fórmula de geração Proth.
Edit: Eu acho que é realmente possível combinar um número Proth diretamente contra um número unário com uma única regex. Atualmente, isso leva 47 bytes, 7 bytes a mais que o meu código Retina atual para verificar se um número unário é um número Proth:
fonte
Regex ECMAScript, 42 bytes
Experimente online! (Usando Retina)
Subtraio 1 essencialmente, divido pelo maior número ímpar possível e
k
, em seguida, verifico se pelo menosk+1
resta.Acontece que minha expressão regular é muito semelhante à que Neil dá no final de sua resposta . Eu uso em
x(xx)*
vez de(x*)\2x
. E eu uso um método mais curto para verificark < 2^n
fonte
(\3\3)*)$
para(\3\3)*$)
$=
e$.=
. Pode ser melhorado ainda melhor .Flak cerebral , 128 bytes
Experimente online!
Eu usei um algoritmo muito diferente do que a solução anterior Brain-Flak .
Basicamente, divido por 2 (arredondando para cima) até atingir um número par. Depois, apenas comparo o resultado da última divisão com os dois ao poder do número de vezes que dividi.
Explicação:
fonte
Maple, 100 bytes (incluindo espaços)
Espaçoso para facilitar a leitura:
Mesma ideia que várias outras; divida X por 2 até X não ser mais divisível por 2 e verifique os critérios 2 ^ n> x.
fonte
Java 1.7,
4943 bytesMais 6 bytes de poeira graças a @charlie.
Tente! (ideona)
Duas maneiras, igualmente longas. Como na maioria das respostas aqui, os créditos vão para @Dennis, é claro, para a expressão.Tomando a raiz do lado direito da expressão:
Aplicando potência de dois no lado esquerdo da expressão:
Pode cortar um único byte se um valor numérico positivo tiver permissão para representar 'verdade' e um valor negativo 'falso':
Infelizmente, por causa da 'Narrowing Primitive Conversion', não se pode simplesmente escrever isso em Java e obter resultados corretos:
E qualquer tentativa de ampliar 'p' levará a um erro de compilação, porque os operadores bit a bit não são suportados, isto é, flutuadores ou duplos :(fonte
boolean f(int p){return Math.sqrt(p--)<(p&-p);}
boolean g(int p){return p--<(p&-p)*(p&-p);}
Math.*
ligações; simplesmente não conseguia descobrir como! Obrigado!Hy , 37 bytes
Experimente online!
Porto da resposta de @Dennis.
fonte
C (gcc) , 29
30bytesExperimente online!
fonte
Japonês ,
12109 bytesExperimente online!
A Geléia do Porto de Dennis responde novamente. - 1 graças a @Shaggy.
fonte
-1
pode serÉ
.Cjam, 11 bytes
Como muitos de nós, pegando carona na excelente solução de Dennis:
Experimente online
fonte
C (137 bytes)
Só vim ler as respostas depois que eu tentei.
Considerando
N=k*2^n+1
com a condição dek<2^n
(k=1,3,5..
en=1,2,3..
Com
n=1
nós temos umk
disponível para testar. À medida que aumentamos,n
temos mais algunsk's
para testar assim:n = 1; k = 1
n = 2; k = 1 k = 3
n = 3; k = 1 k = 3 k = 5 k = 7
...
Iterando essas possibilidades, podemos ter certeza de que N não é um número de Prouth se, por um determinado
n
período,k=1
número obtido for maior que N e nenhuma outra iteração corresponder.Então, meu código basicamente "força bruta" para encontrar N.
Depois de ler as outras respostas e perceber que você pode fatorar N-1 com 2 para encontrar
n
e condicionark<2^n
, acho que meu código pode ser menor e mais eficiente usando esse método.Valeu a tentativa!
Testou todos os números fornecidos e alguns números "não Prouth". A função retorna 1 se o número for um número Prouth e 0 se não for.
fonte
Javascript ES7, 16 bytes
Porto da minha resposta Julia, que é um porto da resposta @ Dennis's Jelly.
Obrigado @Charlie por 2 bytes salvos!
fonte
n=x=>x-1&1-x>x**.5; n(3)
dá-me0
(na verdade, ele me dá 0, independentemente da entrada)n=x=>x-1&1-x>Math.pow(x,0.5); n(3)
(x-1&1-x)
como sem ela a precedência do operador é realmente:(x-1)&((1-x)>x**.5)
x=>x--**.5<(x&-x)
oux=>x**.5<(--x&-x)
C # (.NET Core) , 17 bytes
Experimente online!
Porta da resposta C da MegaTom .
Tentei uma solução baseada em LINQ, mas isso foi bom demais.
fonte
tinta , 60 bytes
Experimente online!
Com base na resposta do @ DSkoog's Maple - não foi o primeiro do gênero a ser publicado, mas foi o primeiro do gênero que eu vi.
Ungolfed
fonte
Código da máquina x86, 15 bytes
Esses bytes definem uma função que recebe o argumento de entrada (um número inteiro não assinado) no
EDI
registro, seguindo a convenção de chamada padrão do System V para sistemas x86 e retorna o resultado noEAX
registro, como todos os as convenções de chamada x86.Em mnemônicos montadores:
Experimente online!
É uma solução bastante direta - e conceitualmente semelhante à versão C da MegaTom . Na verdade, você pode escrever isso em C da seguinte maneira:
mas o código de máquina acima é mais eficiente do que o obtido em um compilador C, mesmo quando ele está configurado para otimizar o tamanho.
O único "truque" aqui está retornando -1 como um valor "verdade" e 0 como um valor "falso". Este truque permite o uso da
SBB
instrução de 2 bytes em oposição à instrução de 3 bytesSETB
.fonte