Nous aimerions factoriser un semi-premier . Le but de ce défi est de trouver deux petits entiers u et v tels que u v N peut être trivialement factorise avec la méthode de Fermat, permettant ainsi de déduire facilement les facteurs de N .
La tâche
Étant donné un semi-premier et un entier positif k , nous définissons x et y comme:
y=x2-kN
Étape # 1 - Trouvez
Vous devez d'abord trouver la plus petite valeur possible de telle que y soit un nombre carré ( aka carré parfait).
Cela permet de factoriser avec une seule itération de la méthode de factorisation de Fermat . Plus concrètement, cela conduit immédiatement à:
(Mise à jour: cette séquence est maintenant publiée sous A316780 )
Étape # 2 - Factoriser
Il faut ensuite trouver les deux entiers positifs et v tels que:
c u = x + √
où et d sont les facteurs premiers de N .
Sommaire
Votre tâche consiste à écrire un programme ou une fonction qui prend comme entrée et imprime ou affiche u et v dans n'importe quel ordre et dans n'importe quel format raisonnable.
Exemple
Considérons
Étape 1
La plus petite valeur possible de est 40 , ce qui donne:
y=28232-40×199163=7969329-7966520=2809=532kN=(2823+53)
Étape 2
La factorisation correcte de est k = 4 × 10 , car:
k N = ( 719 × 4 ) ×
Donc, la bonne réponse serait soit
Règles
- L'entrée est garantie comme un semi-premier.
- Il s'agit de code-golf, donc la réponse la plus courte en octets l'emporte.
- Les failles standard sont interdites.
Cas de test
N | k | Output
-----------+------+------------
143 | 1 | [ 1, 1 ]
2519 | 19 | [ 1, 19 ]
199163 | 40 | [ 4, 10 ]
660713 | 1 | [ 1, 1 ]
4690243 | 45 | [ 9, 5 ]
11755703 | 80 | [ 40, 2 ]
35021027 | 287 | [ 7, 41 ]
75450611 | 429 | [ 143, 3 ]
806373439 | 176 | [ 8, 22 ]
1355814601 | 561 | [ 17, 33 ]
3626291857 | 77 | [ 7, 11 ]
6149223463 | 255 | [ 17, 15 ]
6330897721 | 3256 | [ 74, 44 ]
Exemple d'implémentation
Dans l'extrait ci-dessous, la fonction est une implémentation non gérée qui prend N
la source
N
sera en fait un semi-premier?Réponses:
Mathematica,
8179 octetsMerci à Martin Ender pour avoir économisé 2 octets!
Fonction pure prenant un semi-premier en entrée et renvoyant une paire ordonnée d'entiers positifs. La
For
boucle implémente la procédure exacte décrite dans la question (en utilisant#
pour l'entrée à la place den
), avecx
comme défini ici, bien que nous stockions à laj = k*n
place dek
lui-même etz=Sqrt[y]
au lieu dey
lui - même. Nous calculons égalementp={x+z,x-z}
à l'intérieur de laFor
boucle, ce qui finit par économiser un octet (comme pour le septième essai). Ensuite, les deux facteurs souhaités sont(x+z)/GCD[#,x+z]
et(x-z)/GCD[#,x-z]
, que l'expression concisep/#~GCD~p
calcule directement comme une paire ordonnée.Curiosités: nous voulons boucler jusqu'à ce que
z
soit un entier; mais comme nous allons utiliserCeiling
déjà dans le code, il économise deux octets de plus!IntegerQ@z
à définirc=Ceiling
(ce qui coûte quatre octets, comme le savent les golfeurs de Mathematica), puis teste sic@z>z
. Nous devons initialiserz
à quelque chose, et que quelque chose vaut mieux ne pas être un entier pour que la boucle puisse démarrer; heureusement,E
c'est un choix concis.la source
JavaScript (ES7),
8681 octetsEdit: 4 octets enregistrés grâce à @Arnauld.
la source
Python 2,
127121117 11711110710410199 octets-1 octet grâce à Neil & -3 octets grâce à ovs
Essayez-le en ligne!
Curiosités:
p
est initialisé à.5
pour que la condition de boucle soit vraie à la première itération. Notez qu'il est plus court de stockerp
(en tant quex
+sqrt(y)
) que de stocker chacunx
ety
séparément.la source
x*x
au lieu dex**2
?Axiome,
131115 octetsLa fonction qui résoudrait la question est r (n) ci-dessus. ungolf et test
la source