Votre objectif est de déterminer si un nombre donné n
est premier dans le moins d'octets. Mais, votre code doit être une seule expression Python 2 sur des nombres composés uniquement de
- les opérateurs
- la variable d'entrée
n
- constantes entières
- parenthèses
Pas de boucles, pas d'affectations, pas de fonctions intégrées, seulement ce qui est indiqué ci-dessus. Oui c'est possible.
Les opérateurs
Voici une liste de tous les opérateurs de Python 2 , qui incluent les opérateurs arithmétiques, au niveau du bit et logiques:
+ 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
Toutes les valeurs intermédiaires sont des entiers (ou False / True, ce qui équivaut implicitement à 0 et 1). L'exponentiation ne peut pas être utilisée avec des exposants négatifs, car cela peut produire des flottants. Notez que la /
division au sol, contrairement à Python 3, //
n'est donc pas nécessaire.
Même si vous n'êtes pas familier avec Python, les opérateurs devraient être assez intuitifs. Voir ce tableau pour la priorité des opérateurs et cette section et ci-dessous pour une spécification détaillée de la grammaire. Vous pouvez exécuter Python 2 sur TIO .
E / S
Entrée: un entier positif n
d'au moins 2.
Sortie: 1 si n
est premier et 0 sinon. True
et False
peut également être utilisé. Le moins d'octets gagne.
Étant donné que votre code est une expression, il s'agira d'un extrait de code, qui attend la valeur d'entrée stockée en tant que n
et évalue la sortie souhaitée.
Votre code doit fonctionner pour n
des limites arbitrairement grandes, système mis à part. Étant donné que le type de nombre entier de Python est illimité, il n'y a pas de limites sur les opérateurs. Votre code peut toutefois être long à exécuter.
Réponses:
43 octets
Essayez-le en ligne!
La méthode est similaire à la deuxième réponse (supprimée) de Dennis, mais cette réponse est plus facile à prouver.
Preuve
Forme courte
Le chiffre le plus significatif de2n n
(4**n+1)**n%4**n**2
dans la base qui n'est pas divisible par n fera le chiffre suivant (moins significatif) en non nul (si ce "chiffre suivant" n'est pas dans la partie fractionnaire), alors a avec le masque binaire est exécuté pour vérifier si un chiffre à une position impaire est différent de zéro.(4**n+1)**n%4**n**2/n
&
2**(2*n*n+n)/-~2**n
Forme longue
Soit le nombre ayant cette représentation de base b , c'est-à-dire a n b n + ⋯ + a 1 b 1 + a 0 b 0 , et a i le chiffre à " position " i dans la représentation de base b .[an,…,a1,a0]b b anbn+⋯+a1b1+a0b0 ai i b
Parce que (avecn2n-1s) est un entier, et⌊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
Ensuite, considérez
2 n ( n4n2=(2n)2n , donc 2n (nn)
%4**n**2
tronquera le nombre à derniers chiffres - ce qui exclut le (qui est 1) mais inclut tous les autres coefficients binomiaux.À propos de
/n
:Si est un nombre premier, le résultat sera . Tous les chiffres en position impaire sont nuls.[ ( nn [(nn−1)/n,0,…,0,(n1)/n,0,0]2n
Si n'est pas un nombre premier:n
Soit le plus grand entier tel que ( ). Réécrivez le dividende commea n∤(na) n>a>0
Le premier sommet a tous les chiffres divisibles par , et le chiffre à la position zéro.n 2a−1
La deuxième somme a son chiffre le plus significatif (à la position ) non divisible par et (la base) , donc le quotient en divisant cela par aurait le chiffre à la position non nul.2a n 2n>n n 2a−1
Par conséquent, le résultat final (2n 2a+1
(4**n+1)**n%4**n**2/n
) devrait avoir le chiffre (base , bien sûr) à la position différent de zéro.Enfin, l'ET au niveau du bit (2n a&0=0,a&(2n−1)=a 0≤a<2n n n
&
) effectue un AND au niveau du vecteur vectorisé sur les chiffres de la base (car la base est une puissance de 2), et parce pour tout , est nul ssi tous les chiffres sont dans les premières positions impaires zéro - ce qui équivaut à étant premier.(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n
(4**n+1)**n%4**n**2/n
la source
(4**n+1)**n%2**n**2/n&2**n**2/-~2**n<1
marcherait?n
ne provoquant pas d'interactions indésirables entre la base des chiffres4**n
.(4**n+1)**n%4**n**2/n<<n&4**n**2/-~2**n<1
. Je suis curieux de savoir si ce défi est possible sans opérateurs au niveau du bit.Python 2 , 56 octets
Essayez-le en ligne!
Ceci est une preuve de concept que ce défi est réalisable avec seulement des opérateurs arithmétiques, en particulier sans bitwise
|
,&
ou^
. Le code utilise des opérateurs de bits et de comparaison uniquement pour le golf, et ils peuvent facilement être remplacés par des équivalents arithmétiques.Cependant, la solution est extrêmement lente, et je n'ai pas pu exécuter `, grâce à des exposants à deux niveaux comme .n=6 2nn
L'idée principale est de faire une expression pour le factoriel, ce qui nous permet de faire un test de primalité du théorème de Wilson où est l'opérateur modulo.n! (n−1)!%n>n−2 %
Nous pouvons faire une expression pour le coefficient binomial , qui est composé de factorielles
Mais il n'est pas clair comment extraire un seul de ces factoriels. L'astuce consiste à marteleren faisant vraiment énorme.n! m
Donc, si nous laissons le produit , nous avonsc (1−1m)(1−2m)⋯(1−n−1m)
Si nous pouvions simplement ignorer , nous aurions fini. Le reste de cet article examine la taille dont nous avons besoin pour faire pour pouvoir le faire.c m
Notez que approche par le bas comme . Nous avons juste besoin de faire assez grand pour que l'omission de nous donne une valeur avec la partie entièreafin que nous puissions calculerc 1 m→∞ m c n!
Pour cela, il suffit d'avoirpour éviter que le rapport ne passe le prochain entier .1−c<1/n! n!+1
Remarquez que est un produit de termes dont le plus petit est . Nous avons doncc n (1−n−1m)
ce qui signifie . Puisque nous cherchons à avoir, il suffit de prendre .1−c<n2m 1−c<1/n! m≥n!⋅n2
Dans le code, nous utilisons . Depuis le théorème de Wilson utilise, nous n'avons en fait besoin que de . Il est facile de voir que satisfait la limite pour les petites valeurs et dépasse rapidement le côté droit asymptotiquement, par exemple avec l'approximation de Stirling .m=nn (n−1)! m≥(n−1)!⋅(n−1)2 m=nn
la source
Cette réponse n'utilise aucune intelligence théorique des nombres. Il spams les opérateurs au niveau du bit de Python pour créer un manuel "for loop", vérifiant toutes les paires pour voir si .1≤i,j<n i×j=n
Python 2, beaucoup trop d'octets (278 merci à Jo King dans les commentaires!)
Essayez-le en ligne!
C'est beaucoup plus d'octets que les autres réponses, donc je ne le laisse pas pour l'instant. L'extrait de code ci-dessous contient des fonctions et des affectations de variables pour plus de clarté, mais la substitution transforme isPrime (n) en une seule expression Python.
Pourquoi ça marche?
Je ferai le même algorithme ici en base 10 au lieu de binaire. Regardez cette fraction soignée:
Si nous mettons une grande puissance de 10 dans le numérateur et utilisons la division de plancher de Python, cela donne une énumération de nombres. Par exemple, avec division au sol, en énumérant les nombres .1015/(9992)=1002003004 1,2,3,4
Disons que nous multiplions deux nombres comme celui-ci, avec différents espacements de zéros. Je placerai des virgules de manière suggestive dans le produit.
Le produit énumère, en séquences à trois chiffres, la table de multiplication jusqu'à 4 fois 4. Si nous voulons vérifier si le nombre 5 est premier, il suffit de vérifier si apparaît n'importe où dans ce produit.005
Pour ce faire, nous XOR le produit ci-dessus par le numéro , puis soustrayons le numéro . Appelez le résultat . Si est apparu dans l'énumération de la table de multiplication, cela entraînera le report de la soustraction et mettra à la place correspondante en .005005005…005 001001001…001 d 005 999 d
Pour tester ce débordement, nous calculons un ET de et le nombre . Le résultat est nul si et seulement si 5 est premier.d 900900900…900
la source