Seu objetivo é determinar se um determinado número n
é primo no menor número de bytes. Mas, seu código deve ser uma única expressão Python 2 em números que consistem em apenas
- operadores
- a variável de entrada
n
- constantes inteiras
- parênteses
Sem loops, sem atribuições, sem funções internas, apenas o que está listado acima. Sim é possivel.
Operadores
Aqui está uma lista de todos os operadores no Python 2 , que incluem operadores aritméticos, bit a bit e lógicos:
+ adddition
- minus or unary negation
* multiplication
** exponentiation, only with non-negative exponent
/ floor division
% modulo
<< bit shift left
>> bit shift right
& bitwise and
| bitwise or
^ bitwise xor
~ bitwise not
< less than
> greater than
<= less than or equals
>= greater than or equals
== equals
!= does not equal
Todos os valores intermediários são números inteiros (ou Falso / Verdadeiro, que implicitamente são iguais a 0 e 1). A exponenciação não pode ser usada com expoentes negativos, pois isso pode produzir flutuações. Observe que /
a divisão de piso, diferentemente do Python 3, //
não é necessária.
Mesmo se você não estiver familiarizado com o Python, os operadores devem ser bastante intuitivos. Consulte esta tabela para obter precedência do operador e esta seção e abaixo para obter uma especificação detalhada da gramática. Você pode executar o Python 2 no TIO .
I / O
Entrada: um número inteiro positivo n
que é pelo menos 2.
Saída: 1 se n
for primo e 0 caso contrário. True
e False
também pode ser usado. Menos bytes ganha.
Como seu código é uma expressão, ele será um trecho, esperando o valor de entrada armazenado como n
e avaliando a saída desejada.
Seu código deve funcionar para n
limites arbitrariamente grandes do sistema. Como o tipo de número inteiro do Python é ilimitado, não há limites para os operadores. Seu código pode demorar, no entanto, para ser executado.
Respostas:
43 bytes
Experimente online!
O método é semelhante à segunda resposta (excluída) de Dennis, mas é mais fácil provar que está correta.
Prova
Forma curta
O dígito mais significativo da2n n
(4**n+1)**n%4**n**2
base que não é divisível por n fará com que o próximo dígito (menos significativo) seja diferente de zero (se esse "dígito seguinte" não estiver na parte fracionária), então um com a máscara de bit é executado para verificar se qualquer dígito na posição ímpar for diferente de zero.(4**n+1)**n%4**n**2/n
&
2**(2*n*n+n)/-~2**n
Forma longa
Seja o número com essa representação base b , ou seja, a n b n + ⋯ + a 1 b 1 + a 0 b 0 e a i seja o dígito em " posição " i na representação da base b .[an,…,a1,a0]b b anbn+⋯+a1b1+a0b0 ai i b
Porque (comn2n-1s) é um número inteiro e⌊2n2n×4n2−11+2n=2n(2n−1)×(4n)n−14n−1=[2n−1,0,2n−1,0,2n−1,0]2n n 2n−1 ,
=[2n-1,0,2n-1,0,2n-1,0]2n.⌊2n1+2n⌋=0 [2n−1,0,2n−1,0,2n−1,0]2n
2**(2*n*n+n)/-~2**n
Em seguida, considere
, portanto, truncará o número para 2 n últimos dígitos - que exclui o ( n4n2=(2n)2n 2n (que é 1), mas inclui todos os outros coeficientes binomiais.(nn)
%4**n**2
Sobre
/n
:Se for primo, o resultado será [ ( nn . Todos os dígitos na posição ímpar são zero.[(nn−1)/n,0,…,0,(n1)/n,0,0]2n
Se não for primo:n
Seja o maior número inteiro, de modo que n ∤ ( na (n>a>0). Reescreva o dividendo comon∤(na) n>a>0
O primeiro somatório possui todos os dígitos divisíveis por , e o dígito na posição 2 a - 1 zero.n 2a−1
O segundo somatório possui seu dígito mais significativo (na posição ) não divisível por n e (a base) 2 n > n ; portanto, o quociente ao dividir isso por n teria o dígito na posição 2 a - 1 diferente de zero.2a n 2n>n n 2a−1
Portanto, o resultado final (2n 2a+1
(4**n+1)**n%4**n**2/n
) deve ter o dígito (base , é claro) na posição 2 a + 1 diferente de zero.Finalmente, o AND bit a bit2n a&0=0,a&(2n−1)=a 0≤a<2n n n
&
executa um AND vetorizado bit a bit nos dígitos da base (porque a base é uma potência de 2) e porque a & 0 = 0 , a & ( 2 n - 1 ) = a para todos 0 ≤ a < 2 n , é zero se tiver todos os dígitos nas primeiras n posições ímpares zero - o que equivale a n ser primo.(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n
(4**n+1)**n%4**n**2/n
fonte
(4**n+1)**n%2**n**2/n&2**n**2/-~2**n<1
?n
não causar interações indesejadas entre a base de dígitos4**n
.(4**n+1)**n%4**n**2/n<<n&4**n**2/-~2**n<1
. Estou curioso para saber se esse desafio é possível sem operadores bit a bit.Python 2 , 56 bytes
Experimente online!
Esta é uma prova de conceito de que este desafio é factível apenas com operadores aritméticos, em particular, sem bit a bit
|
,&
ou^
. O código usa operadores bit a bit e de comparação apenas para jogar golfe, e eles podem ser facilmente substituídos por equivalentes aritméticos.No entanto, a solução é extremamente lenta e não consegui executar `, graças a expoentes de dois níveis, como 2 n n .n=6 2nn
A idéia principal é fazer uma expressão para o fatorial , o que nos permite fazer um teste de primalidade do teorema de Wilson ( n - 1 ) ! % n > n - 2 onde % é o operador de módulo.n! (n−1)!%n>n−2 %
Podemos fazer uma expressão para o coeficiente binomial , que é feito de fatoriais
Mas não está claro como extrair apenas um desses fatoriais. O truque é separar fazendo m realmente enorme.n! m
If we could just ignorec , we'd be done. The rest of this post is looking how large we need to make m to be able to do this.
Note thatc approaches 1 from below as m→∞ . We just need to make m huge enough that omitting c gives us a value with integer part n! so that we may compute
For this, it suffices to have1−c<1/n! to avoid the ratio passing the next integer n!+1 .
Observe thatc is a product of n terms of which the smallest is (1−n−1m) . So, we have
which means1−c<n2m . Since we're looking to have 1−c<1/n! , it suffices to take m≥n!⋅n2 .
In the code, we usem=nn . Since Wilson's Theorem uses (n−1)! , we actually only need m≥(n−1)!⋅(n−1)2 . It's easy to see that m=nn satisfies the bound for the small values and quickly outgrows the right hand side asymptotically, say with Stirling's approximation.
fonte
This answer doesn't use any number-theoretic cleverness. It spams Python's bitwise operators to create a manual "for loop", checking all pairs1≤i,j<n to see whether i×j=n .
Python 2, way too many bytes (278 thanks to Jo King in the comments!)
Try it online!
This is a lot more bytes than the other answers, so I'm leaving it ungolfed for now. The code snippet below contains functions and variable assignment for clarity, but substitution turns isPrime(n) into a single Python expression.
Why does it work?
I'll do the same algorithm here in base 10 instead of binary. Look at this neat fraction:
If we put a large power of 10 in the numerator and use Python's floor division, this gives an enumeration of numbers. For example,1015/(9992)=1002003004 with floor division, enumerating the numbers 1,2,3,4 .
Let's say we multiply two numbers like this, with different spacings of zeroes. I'll place commas suggestively in the product.
The product enumerates, in three-digit sequences, the multiplication table up to 4 times 4. If we want to check whether the number 5 is prime, we just have to check whether005 appears anywhere in that product.
To do that, we XOR the above product by the number005005005…005 , and then subtract the number 001001001…001 . Call the result d . If 005 appeared in the multiplication table enumeration, it will cause the subtraction to carry over and put 999 in the corresponding place in d .
To test for this overflow, we compute an AND ofd and the number 900900900…900 . The result is zero if and only if 5 is prime.
fonte