(EDIT By Excale: Je n'ai gardé que la version Axe z80, mais reste les commentaires basic+nspire) * * * Concours d'algorithmique * * * * * * Abréviations PP : (Nombre) Premier Palindrome PL : Palindrome PR : Premier * * * Explication de l'algorithme Soit X le paramètre envoyé. Si X<6, on exécute un code spécifique pour les PP inférieurs à 100 : Boucle qui vérifie, depuis 2, si I est PR : les 5 premiers PR sont tous PL On retourne le nombre quand on en a trouvé X. //Code pour X>=6, PP>=100 On initialise F (nombre de PP trouvés) à 5 pour les PP de 2 à 11 On initialise B (base 10) à 0 pour que ça soit à 1 au début Une boucle infinie incrémente B E prend la valeur 10^B-1 pour avoir E=10^B au début ensuite Boucle tant que E n'a pas atteint la valeur maximale en gardant B+1 chiffres On construit un PL avec E : 56->565 ; 721->72127 Si le PL finit par 2,4,5,6 ou 8 on incrémente le premier chiffre de E : E+10^B->E P prend la valeur du PL Si P n'est divisible ni par 3 ni par 7, on regarde s'il est PR S'il l'est, on incrémente F On retourne P lorqu'on a F=X //Construction du PL On calcule le nombre de chiffres de X On construit C avec une boucle : Si X=5906 alors C=095 On fusionne C et X : X*10^(N)+C et on retourne ce résultat //Savoir si N est PR (BASIC) Une boucle for(I,10,sqrt(N)) (N n'est pas divisible par 2, 3, 5, 7 et sqrt(N) empêche d'aller trop loin) On incrémente I à nouveau pour qu'il soit toujours impair Boucle : tant que I est divisible par 3, 5 ou 7, on lui ajoute 2 N n'est pas PR s'il est divisible par I ( soit mod(N,I)=0 ou fPart(N/I)=0 ) A la fin de la boucle, on retourne 1 ou true car si on est arrivé là c'est que N est PR. * * * Optimisations/Spécificités BASIC Nspire Utilisation de A comme de variable Ans à cause de dysfonctionnements Raccourcissement des noms de variables à une seule lettre Déclaration interne des fonctions Utilisation de deux fonctions isPR : une pour X<6, complète, et l'autre optimisée pour la vitesse * * * Optimisations/Spécificités BASIC z80 Utilisation de A comme de variable Ans à cause de dysfonctionnements Système de Lbls/Gotos pour éviter les programmes externes Parenthèses non refermées (c'est plus léger * * * Optimisations/Spécificités Asm (Axe 1.2.1) z80 Wrapper pour gérer l'envoi du résultat dans Ans On retourne 0 si X>70 car PP(71)=70207, nombre inatteignable en asm z80 On retourne 2 si X=1 Subroutine intégrée au code "si X<6" (pas d'appel de routine ou de goto) * * Note : la commande Asm(34) incrémente l'octet pointé par HL, soit celui qui se trouve à l'adresse contenue par la dernière valeur entrée : ici, °K pointe donc K. A l'inverse, Asm(35) décrémente l'octet pointé. Optimisation du 5->F:9->E : 9 prend 3 octets alors que *2-1 n'en prend que 2 La routine de construction du PL n'est pas appellée, elle est intégrée dans la boucle While 1:EndIf La routine de construction du PL ne gère que les cas "X<100" et "X>=100" car ce sont les seuls utiles La vérification "K est-il PR" se fait avec la routine IP() IP() ne prend pas de paramètres réellement, elle prend comme paramètre K d'office : gain de 6 octets par appel IP() ne retourne pas de valeur mais incrémente F si K est PR : c'est plus rapide et pratique * * * Utilisations Nspire : Ouvrir le classeur, seule la fonction palprem est à prendre en compte. palprem(42) retourne 18181 *Note: le programme testor permet de calculer plus précisément le temps pris par la fonction BASIC z80 : 42:prgmPALPREM:Ans affiche 18181 Asm (Axe) z80 : A cause d'un nom dupliqué, le programme compilé s'appelle par défaut PALPREMX ( la source s'appelle APLPR2 ) 42:Asm(prgmPALPREMX):Ans affiche 18181 * * * Temps Pour PP(42), les temps sont d'environ : Nspire : 002.93 secondes BASIC z80 : 121.79 secondes Asm (Axe) z80 : 000.95 secondes Pour PP(20) = 929, les temps sont d'environ : Nspire : 000.42 secondes BASIC z80 : 012.45 secondes Asm (Axe) z80 : 000.14 secondes (les petites mesures ont été réalisées sur 50 (Nspire) et 100 (Axe) appels de fonctions)