Considérez la fonction Remove(n, startIndex, count)
qui supprime les count
chiffres du nombre n
à partir du chiffre à la position startIndex
. Exemples:
Remove(1234, 1, 1) = 234
Remove(123456, 2, 3) = 156
Remove(1507, 1, 2) = 07 = 7
Remove(1234, 1, 4) = 0
Nous appellerons le nombre premier X fragile si chaque Remove
opération possible le rend non premier. Par exemple, 80651 est un nombre premier fragile car tous les nombres suivants ne sont pas premiers:
651, 51, 1, 0, 8651, 851, 81, 8, 8051, 801, 80, 8061, 806, 8065
Objectif
Écrivez un programme qui trouve le plus grand nombre premier fragile. Edit: suppression du délai, car il y avait un moyen relativement juste de le contourner.
Le score est le nombre premier fragile trouvé par votre programme. En cas d'égalité, la soumission précédente l'emporte.
Règles
- Vous pouvez utiliser n'importe quelle langue et toute bibliothèque tierce.
- Vous exécutez le programme sur votre propre matériel.
- Vous pouvez utiliser des tests de primalité probabilistes.
- Tout est en base 10.
Entrées principales
- 6629 chiffres par Qualtagh (Java)
- 5048 chiffres par Emil (Python 2)
- 2268 chiffres par Jakube (Python 2)
Edit: j'ai ajouté ma propre réponse.
- 28164 chiffres par Suboptimus Prime, basé sur l'algorithme de Qualtagh (C #)
code-challenge
primes
Suboptimus Prime
la source
la source
Réponses:
Java -
314433226629 chiffres6 0{3314} 8969999
Cette solution est basée sur la réponse de FryAmTheEggman .
Et si nous creusons plus profondément?
Cela devient une structure arborescente:
Appelons le nombre R composé droit si R et toutes ses terminaisons sont composites.
Nous allons itérer sur tous les bons nombres composites de la manière la plus large: 1, 9, 01, 81, 91, 09, 49, 69, 99, 001, 801, 901, etc.
Les nombres commençant par zéro ne sont pas vérifiés pour la primauté mais sont nécessaires pour construire d'autres nombres.
Nous chercherons un nombre cible N sous la forme X00 ... 00R, où X est l'un des 4, 6, 8 ou 9 et R est le composite de droite. X ne peut pas être premier. X ne peut pas être 0. Et X ne peut pas être 1 car si R se termine par 1 ou 9 alors N contiendrait 11 ou 19.
Si XR contient des nombres premiers après l'opération de "suppression", alors XYR les contiendrait également pour tout Y. Nous ne devrions donc pas traverser les branches à partir de R.
Soit X une constante, disons 6.
Pseudocode:
Nous devons limiter la quantité de zéros car cela peut prendre trop de temps pour trouver un nombre premier sous la forme X + zéros + R (ou pour toujours si tous sont composites).
Le vrai code est assez verbeux et peut être trouvé ici .
Le test de primalité pour les nombres à longue distance int est effectué par une variante déterministe du test de Miller. Pour les nombres BigInteger, une division d'essai est effectuée en premier, puis le test BailliePSW. C'est probabiliste mais assez certain. Et c'est plus rapide que le test de Miller-Rabin (nous devrions faire de nombreuses itérations pour de si grands nombres dans Miller-Rabin pour gagner suffisamment de précision).
Edit: la première tentative était incorrecte. Nous devons également ignorer les branches commençant par R si X0 ... 0R est premier. Alors X0 ... 0YR ne serait pas un premier fragile. Une vérification supplémentaire a donc été ajoutée. Cette solution semble être correcte.
Edit 2: ajout d'une optimisation. Si (X + R) est divisible par 3, alors (X + zéros + R) est également divisible par 3. Donc (X + zéros + R) ne peut pas être premier dans ce cas et de tels R peuvent être ignorés.
Edit 3: il n'était pas nécessaire de sauter les premiers chiffres s'ils ne sont pas dans la dernière ou la première position. Les terminaisons comme 21 ou 51 sont donc correctes. Mais cela ne change pas grand-chose.
Conclusions:
la source
Python
2-1261221133717192268 chiffresIl y a environ len (n) ^ 2 nombres résultants de Remove (n, startIndex, count). J'ai essayé de minimiser ces chiffres. S'il y a beaucoup de chiffres côte à côte, beaucoup de ces nombres résultants peuvent être ignorés, car ils apparaissent plusieurs fois.
Je l'ai donc poussé à l'extrême, seulement 9s et un peu prime au milieu. J'ai également jeté un coup d'œil au premier fragile de moins d'un million et j'ai vu qu'il y avait un tel premier fragile. La recherche de nombres avec 2 9 à la fin fonctionne vraiment bien, je ne sais pas pourquoi. 1 nombre, 3 ou 4 9 à la fin entraîne des nombres premiers fragiles plus petits.
Il utilise le module pyprimes . Je ne sais pas si c'est bon. Il utilise le test miller_rabin, il est donc probabiliste.
Le programme trouve ce premier fragile à 126 chiffres en environ 1 minute, et pour le reste du temps, il cherche sans succès.
Éditer:
Je viens de voir que vous avez supprimé le délai. Je vais exécuter le programme pendant la nuit, peut-être que de très gros nombres premiers fragiles apparaissent.
modifier 2:
J'ai rendu mon programme original plus rapide, donc mais toujours pas de solution avec plus de 126 chiffres. J'ai donc sauté dans le train et recherché x 9s + 1 chiffre + y 9s. L'avantage est que vous devez vérifier la primauté des nombres O (n) si vous fixez y. Il trouve un 1221 assez rapidement.
modifier 3:
Pour le nombre de 2268 chiffres, j'utilise le même programme, divisé uniquement le travail sur plusieurs cœurs.
la source
Python 2.7 - 429623069
99993799Jusqu'à présent, aucune optimisation. Juste en utilisant quelques observations triviales sur les nombres premiers fragiles (grâce à Rainbolt dans le chat):
J'essaie juste de faire rouler la balle :)
Cela dure techniquement un peu plus de 15 minutes, mais il ne vérifie qu'un seul numéro dans le temps supplémentaire.
is_prime
est tiré d' ici (isaacg l'a utilisé ici ) et est probabiliste.Juste une note, quand je commence ça,
n=429623069
je me lève482704669
. Le chiffre supplémentaire semble vraiment tuer cette stratégie ...la source
Python 2,
828 chiffres5048 chiffresComme l'a souligné @Jakube, le premier Prime que j'ai soumis n'était pas réellement fragile en raison d'un bogue dans mon code. La correction du bogue était facile mais cela a également rendu l'algorithme beaucoup plus lent.
Je me suis limité à un sous-ensemble facilement interrogeable des nombres premiers fragiles, à savoir ceux qui ne comprennent que le chiffre 9 et exactement un chiffre 7.
J'ai utilisé la même
is_prime
fonction (d' ici ) que @FryAmTheEggman.Éditer:
J'ai fait deux changements pour accélérer l'algorithme:
J'essaie d'ignorer autant de vérifications de primalité que possible et de ne revenir en arrière que lorsqu'un premier potentiel fragile est trouvé pour m'assurer qu'il est vraiment fragile. Il y a un petit nombre de vérifications en double, donc j'ai mémorisé grossièrement la fonction de vérification principale.
Pour les numéros du formulaire,
b*'9' + '7' + c*'9'
j'ai limité la taille deb
. Plus la limite est basse, moins les nombres doivent être vérifiés, mais les chances augmentent de ne trouver aucun grand premier fragile. J'ai en quelque sorte choisi arbitrairement 222 comme limite.À quelques milliers de chiffres, une seule vérification principale peut déjà prendre quelques secondes mon programme. Donc, je ne peux probablement pas faire beaucoup mieux avec cette approche.
N'hésitez pas à vérifier l'exactitude de ma soumission. En raison du contrôle de primalité probabiliste, mon nombre ne pourrait théoriquement pas être premier, mais s'il l'est, il devrait être fragile. Ou j'ai fait quelque chose de mal. :-)
la source
C #,
1003928164 chiffresEdit: J'ai fait un autre programme basé sur l'algorithme de Qualtagh avec quelques modifications mineures:
Ancienne réponse:
Voici quelques schémas notables pour les nombres premiers fragiles:
où X peut être 1, 2, 4, 5, 7 ou 8.
Pour de tels nombres, nous n'avons qu'à considérer (longueur - 1) les
Remove
opérations possibles . L'autreRemove
opérations produisent soit des doublons, soit des nombres évidemment composites. J'ai essayé de rechercher tous ces numéros avec jusqu'à 800 chiffres et j'ai remarqué que 4 modèles apparaissent plus fréquemment que les autres: 8007001, 8004001, 9997999 et 6004009. Puisque Emil et Jakube utilisent le modèle 999X999, j'ai décidé d'utiliser 8004001 juste pour ajouter de la variété.J'ai ajouté les optimisations suivantes à l'algorithme:
la source
Haskell -
12201277 chiffres fixes pour vraiment réelsMieux - 1277 chiffres
Code Haskell
la source