La tâche consiste à trouver un facteur non trivial d'un nombre composite.
Écrivez le code qui trouve le plus rapidement possible un facteur non trivial d'un nombre composite, sous réserve que votre code ne dépasse pas 140 octets. La sortie doit simplement être le facteur que vous avez trouvé.
Votre code peut prendre des entrées et donner des sorties de n'importe quelle manière, y compris par exemple en tant qu'arguments à une fonction.
Cas de test qui répertorient tous les facteurs (il vous suffit d'en générer un)
187: 11 17
1679: 23 73
14369648346682547857: 1500450271 9576890767
34747575467581863011: 3628273133 9576890767
52634041113150420921061348357: 2860486313 5463458053 3367900313
82312263010898855308580978867: 264575131106459 311111111111113
205255454905325730631914319249: 2860486313 71755440315342536873
1233457775854251160763811229216063007: 1110111110111 1000000000063 1111111999999
1751952685614616185916001760791655006749: 36413321723440003717 48112959837082048697
Je ne marquerai pas votre réponse sur le cas de test difficile suivant qui peut être intéressant pour le test:
513231721363284898797712130584280850383: 40206835204840513073 12764787846358441471
But
Votre score est le temps combiné pour factoriser tous les cas de test ci-dessus avec une pénalité de 10 minutes pour chaque factorisation échouée (tous arrondis à la seconde la plus proche). Votre code devrait également fonctionner pour d'autres entiers, c'est-à-dire ne devrait pas simplement coder en dur ces réponses.
Je vais arrêter votre code après 10 minutes.
Si deux personnes obtiennent le même score, la première réponse l'emporte.
Restrictions
Votre code ne peut pas utiliser de fonction intégrée ou de bibliothèque qui effectue une factorisation entière. Vous pouvez supposer que l'entrée prend moins de 256 bits. Tous les numéros d'entrée seront composites.
Comment vais-je chronométrer?
Je vais littéralement fonctionner time ./myprog
sur mon système Ubuntu pour faire le chronométrage, veuillez donc également fournir un programme complet à exécuter pour moi qui inclut toute fonction que vous avez définie.
Une note pour les langues compilées
Le temps de compilation ne doit pas prendre plus d'une minute sur ma machine.
Est-ce réellement possible?
Si vous ignorez les contraintes d'espace, alors chacune peut être prise en compte en moins de 2 secondes sur mon ordinateur en utilisant du code Python + pypy pur.
Qu'est-ce qu'un algorithme d'affacturage non trivial?
L'algorithme rho de Pollard est rapide et adapté au golf. Bien sûr, il existe également de nombreuses autres façons de factoriser un entier .
Le tamis quadratique est encore plus rapide . Cela ressemble à un sérieux défi de le compresser en 140 octets.
Principaux scores
- SEJPM , 10 minutes de pénalité pour le dernier cas de test + 16 secondes à Haskell
2 ** 1024
?2
ou2, 2
?Réponses:
Haskell,
100979189877267 octetsEssayez-le en ligne!
-3 octets grâce à @flawr
-6 octets grâce à @flawr encore
-2 octets grâce à @flawr encore
-2 octets grâce à un ensemble optimisé de paramètres
-1 octet grâce à @flawrs encore une fois
-14 octets grâce à l'exigence d'avoir seulement à émettre un facteur
-5 octets grâce à @AndersKaseorg
Cela fonctionne pour les 5 premiers cas de test en un temps inaperçu.
Cela expirera probablement sur le plus grand cas de test.
En général, cela renvoie généralement un facteur non trivial dans le temps proportionnel à la racine carrée du plus petit facteur.
Il ne fonctionnera pas sur chaque entrée car il ne fait pas varier le polynôme et la détection du cas exceptionnel est difficile à faire en 140 octets.
Il ne produira pas non plus la factorisation complète, mais plutôt un facteur non trivial et la division de l'entrée par ce facteur.
Il ne triera pas non plus les facteurs par taille.
La méthode utilisée est Pollard-Rho-Factoring avec la valeur de départ standard de 2 (avec le
x^2+1
polynôme standard appliqué une fois) et le facteur constant polynomial non standard de 7 (car cela1
n'a pas fonctionné avec 1679) pour toutes les évaluations ultérieures.Programme complet (
factor.hs
):Compilez en tant que
$ ghc factor.hs
(besoinsghc
installés).Exécuter en tant que
$ ./factor <number>
.Exemple d'exécution:
Code non golfé:
Calcule le facteur non trivial en appelant
g
avec les valeurs initiales. Le polynôme est pré-appliqué sur 2 ici et ré-appliqué sur le résultat (5) afin que l'entrée deg
(dans une clause "où" ) puisse toujours être facilement utilisée pour le test gcd.g
(la version golfée utilise infixe#
) essaie ensuite de calculer un facteur non triviald
(dans la clause where dans la version non golfée, en ligne dans la version golfée) comme la différence entre les deux entrées àg
, si elle réussit, renvoie ledit facteur , sinon réessaie. Ici, il peut générern
comme sortie sia==b
et ne renvoie donc qu'un facteur trivial, l'approche appropriée pour gérer cela serait soit de faire varier les valeurs de départ lors de cet événement, soit de changer le polynôme.la source
|1<2=s a#(s$s b)
pourrait être remplacé par|c<-s b=s a#s c
je pense :) (aussi: pourquoi ne postez-vous pas un lien TIO ?)abs
, car ilb
est toujours non négatif. (Peut-être que vous vouliez direabs$b-a
, maisgcd
acceptez des arguments négatifs et produit toujours un résultat non négatif.) Cela ramène cela à moins d'un demi-tweet!Pari / GP , 137 octets, ~ 5 secondes
En utilisant les opérations de courbe elliptique intégrées de GP (et certains réglages de paramètres sournois) :
ecm
est une fonction qui (devrait) retourner un facteur. Essayez-le en ligne!Tester:
Non golfé:
Malheureusement, la gestion des facteurs 2 et 3 utilise de nombreux octets. Octets qui auraient pu être utilisés pour ajouter une étape 2:
la source
Axiome, 137 octets 9 minutes
au-dessus de la fonction p () qui implémenterait l'algorithme p-1 pour factoriser ci-dessous ce qu'il faut copier dans un fichier pour tester la fonction p ()
résultats ici:
la source
Axiome, 10 minutes + 31 secondes
z () est la fonction rho, une fonction de 137 octets; ungolfed z () et appelez-le comme rho (). Il supposerait que gcd (0, n) = n donc la boucle s'arrête et revient pour échouer n.
les résultats (z () conviennent à tous, mais le dernier numéro 1751952685614616185916001760791655006749 n'est pas pris en compte (10 minutes))
la source
Python 3 ,
10099 octets,45 4039 secondes + 10 minutes de pénalitéEssayez-le en ligne!
Utilise Pollard-Rho avec la valeur initiale 2 et le polynôme x ^ 2 + 1.
la source
pow
(avec le 3e argument) pour améliorer votre vitesse d'exécution.