En effet, les temps de test de la divisibilité et du calcul des factorielles augmentent exponentiellement.
Voici une version bien plus rapide qui donne les trois résultats en moins de 5 heures
L'accélération est due au fait que le test de divisibilité n'est effectué que pour les nombres premiers.
Le test prend un peu de temps, mais ce temps est rapidement amorti par en évitant une palanquée de tests de divisibilité inutiles.
Par contre la boucle de recherche parcourt touts les entiers afin de construire toutes les factorielles et de mémoriser tous les chiffres.
Pour éviter les erreurs d'arrondi, je ne peux mémorisé dans chaque registre que 7 chiffres (sur les 10 d'un registre SHARP PC-1211). En effet, il faut pouvoir calculer le produit de N (au plus trois chiffres) avec les chiffres de la factorielle et ne pas dépasser 10 pour un résultat correct.
Ce qui pose un problème pour le test de divisibilité. Je ne peux l'effectuer sur les 7 chiffres de chaque registre de la factorielle, car le carré peut lui aussi faire jusqu'à 6 chiffres ce qui va dépasser la capacité de calcul limité à 10 chiffres. Je suis donc obligé de faire le test de divisibilité en deux étape pour chaque registre de la factorielle. En prenant 3 ou 4 chiffres j'obtiens un calcul du module correct.
C'est évidemment plus lent, mais comme le test n'est effectué que pour les nombres premiers, je gagne du temps, surtout vers la fin de la recherche où les nombres premiers sont de plus en plus rares.
Donc, voici le code pour SHARP PC-1211 qui lui fonctionne et donne les trois nombres de Wilson inférieurs à 1000 dont le carré est multiple de la factorielle précédente.
Code : Tout sélectionner
PROGRAMM
1:F=7,G=2:FOR B=3 TO 997:C=B,D=2
2:IF D<C LET C=B/D,D=D+1+(D>2):GOTO 2+2*(C=INT C)
3:C=0:FOR A=F TO 7 STEP -1:E=Ḛ3,D=A(A)/10E:GOSUB 9:E=Ḛ4,D=DE+(A=7):GOSUB 9:D=C:NEXT A:IF D=0 PRINT B
4:C=0,E=Ḛ-7:FOR A=7 TO F:A(A)=BA(A)+C,C=INT EA(A),A(A)=A(A)-C/E:NEXT A:IF C LET F=F+1,A(F)=C
5:NEXT B:END
9:C=CE+INT D,D=D-INT D,C=C-BB*INT (C/BB):RETURN
Code : Tout sélectionner
MEMORIES
1: oo27 Initie F=2!
2: oo37 Test primalité de n
3: oo68 Test divisabilité en deux étapes - calcul F(…) MOD p²
4: oo74 Calcule F(n)=n*F(n-1)
5: ooo7 Boucle pour tous les n
9: oo28 SS-prg calcul modulo
TOT o241 octets
Code : Tout sélectionner
REGISTERS : VARIABLES
Ligne 2:Test Primalité 3:Test Divisibilité 4:Calcul Factorielle 9:Ss-Prg:Calcul Module
A: - i=indice d'F(i) i=indice d'F(i) - -
B: n=nombre recherché p=nombre premier m=multiplicateur IN:p -
C: q=ratio n/d r=retenue modulo n² r=F(…) DIV 1E7 IN:retenue Out:module n²
D: d=diviseurs testés d= <- FFF.ffff(…) - IN:donnée Out:partie fractionaire
E: - e= 1e4 ou 1e3 e=1e7 IN:puissance -
F: - f= ^n° dernier F(…) f= ^n° dernier F(…) - -
G: - F(7)=
… F(…)= Chiffres de la factorielle
A(F): F(F)=
Code : Tout sélectionner
EXECUTION
4'25 24=!( 5.)
16'23 479001600=!( 13.)
4h32'23" …925300632803498973864795497173769781248000000000000000000000…0=!( 563.)