Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Ici, on fait dans le petit, le LCD qui déchire sa race, on y cause même calculatrices quand on est en manque !

Modérateur : Politburo

Répondre
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2931
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par zpalm »

En ce début de week-end, un petit MPO pour muscler les neurones :)

Si l’on considère la suite des nombres premiers décimaux, en ne gardant que ceux qui sont des nombres valides en base 8 (par exemple 31 mais pas 29) et qui dans cette base sont aussi des nombres premiers (par exemple 13 mais pas 17), alors quel est le 52ème élément?

Une prime sera attribuée virtuellement à la machine la plus ancienne :D

Sommaire des MPO.
Avatar du membre
cakeisalie5
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 23
Enregistré le : 14 juin 2017 14:45
Localisation : Brunoy, France
Contact :

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par cakeisalie5 »

Au vu de la collection des personnes d'ici, je suis sûr de perdre pour ce qui concerne l'ancienneté de la machine, mais j'ai tenté quand même sur ma fx-7000G (calculatrice introduite sur le marché en 1985). Ça m'a pris un temps fou parce que je n'ai pas l'habitude du mode d'édition (qui est bien meilleur sur les calculatrices actuelles), et que je fonce sans forcément lire la solution (ce post était entièrement différent avant que je le réécrive parce que je me suis rendu compte que ma solution n'était pas du tout correcte).

Image

Je n'ai pas vérifié la solution que j'ai trouvée (désolé pour l'image un peu sombre), mais mon petit doigt me dit que c'est le bon. ;)
Notez que le calcul de ce résultat a quand même pris un peu plus de onze minutes.

Ma solution est faite de quatre programmes, dont trois annexes :
- Prog 1 : vérifie si un nombre est premier ; prend son argument sur R, pose sa valeur de retour sur P ;
- Prog 2 : convertit un entier octal exprimé en décimal en sa valeur octale, e.g. 13 = 1 x 8^1 + 3 x 8^0 = 11, puis vérifie s'il est premier ; prend son argument sur Q, pose sa valeur de retour sur P ;
- Prog 3 : itère sur A, vérifie que les chiffres décimaux utilisés passent en octal, e.g. 177 -> 200 ; modifie A.

Mon programme principal est tout bête : pour chaque entier produit passé par l'itérateur à partir de 2, il vérifie si le nombre est premier, si sa version octale est première, et s'il est bien le 52ème (s'il y a exactement 51 éléments arrivés jusque là avant).

Voici les sources :

Code : Tout sélectionner

[[ Prog 0 ]]
1->A:52->C
Lbl 0:Prog 3
A->R:Prog 1
P=0=>Goto 0
A->Q:Prog 2
P=0=>Goto 0
C-1->C
C!=0=>Goto 0:A

[[ Prog 1 ]]
1->O:1->P:sqrt R->Y
Lbl 0:O+1->O
O>Y=>Goto 1
R-OxInt (R/O)!=0=>Goto 0
0->P
Lbl 1

[[ Prog 2 ]]
0->R:Int (log Q)+1->N
10^N->M
e(Nxln 8)->N
Lbl 0:M<1=>Goto 1
Int (Q/M)->O
R+OxN->R
Q-OxM->Q
M/10->M:N/8->N
Goto 0
Lbl 1:Prog 1

[[ Prog 3 ]]
0.1->M:A+1->A
Lbl 0:Mx10->M
A<M=>Goto 1
Int (A/M)->D
D-Int (D/10)x10>=8=>A+2xM->A
Goto 0:Lbl 1
Hâte de voir des solutions meilleures que la mienne, qui est assez basique et manifestement pas super optimisée ^^
Auteur et mainteneur du projet P7 pour calculatrices CASIO, dont ma collection est ici. Également sur Mastodon. J'ai réalisé un bot Mastodon pour le forum de Silicum.
Avatar du membre
ledudu
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5643
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par ledudu »

Salut,
En tout cas, tu mets cette machine à l'honneur dans une rubrique qu'elle ne connait guère.
Bravo pour ça !
Avatar du membre
cakeisalie5
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 23
Enregistré le : 14 juin 2017 14:45
Localisation : Brunoy, France
Contact :

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par cakeisalie5 »

C'est vrai qu'elle est peut-être trop récente pour cette rubrique... :P
Au passage, en divisant le nombre d'entiers à tester par deux, alors que ça ne devrait avoir quasiment aucun effet, j'ai gagné presque trois minutes, pour arriver à 8'46"... faut croire que l'appel de sous-programmes consomme beaucoup sur cette calculatrice... Oo

Je fais juste A+2->A dans Prog 3 (avec 51->C dans Prog 0, pour "oublier" le 2) pourtant.
Auteur et mainteneur du projet P7 pour calculatrices CASIO, dont ma collection est ici. Également sur Mastodon. J'ai réalisé un bot Mastodon pour le forum de Silicum.
Avatar du membre
gege
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 7147
Enregistré le : 31 janv. 2008 14:24
Localisation : Banlieue Paârisienne
Contact :

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par gege »

Bonjour,
Bravo pour ce programme, qui est beaucoup beaucoup mieux que le mien (non je n'en ai pas...).
C'est curieux ton style de programmation, chacun a sa personnalité !!
Il est amusant de lire le code des autres.
Sur 7000G on doit composer avec le langage...

Je ne sais pas si tu fais vraiment ce qui est demandé, que je lis comme "ne pas garder les nombres premiers qui ne sont pas des représentations octales valides".
On ne demande pas de convertir l'octal en décimal et de re-tester aussi que le résultat est premier ?
Ou alors j'ai encore mal compris.

Sinon, c'est bizarre d'écrire e(Nxln 8 ) au lieu de 8^N, pourquoi ??
Bon c'est l'heure de sortir une machine, la plus ancienne possible... mmm est-ce qu'elle fonctionne encore ?
G.E.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2931
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par zpalm »

gege a écrit : 17 juin 2017 21:21 Je ne sais pas si tu fais vraiment ce qui est demandé, que je lis comme "ne pas garder les nombres premiers qui ne sont pas des représentations octales valides".
On ne demande pas de convertir l'octal en décimal et de re-tester aussi que le résultat est premier ?
Ou alors j'ai encore mal compris.
cakeisalie5 a bien compris le sujet du MPO. Effectivement il ne faut pas garder les nombres premiers qui ne sont pas des représentations octales valides: par exemple en base 10, 29 est un nombre premier mais 29 n'est pas un nombre valide en base 8.

Mais de plus il faut que la représentation octale soit aussi un nombre premier: 13 en base 10 est un nombre premier et 13 en base 8 est aussi un nombre premier. Par contre si 17 en base 10 est un nombre premier, 17 en base 8 ne l'est pas.
Avatar du membre
cakeisalie5
Fonctionne à 75 bauds
Fonctionne à 75 bauds
Messages : 23
Enregistré le : 14 juin 2017 14:45
Localisation : Brunoy, France
Contact :

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par cakeisalie5 »

gege a écrit :Sinon, c'est bizarre d'écrire e(Nxln 8 ) au lieu de 8^N, pourquoi ??
En fait à ce moment-là, j'avais cherché l'opérateur puissance sur la fx-7000G, et je l'avais pas trouvé. Du coup, je me suis dit que la calculatrice n'en avait pas, et j'ai composé avec, m'auto-persuadant que la calculatrice n'en avait pas et trouvant ça chaud quand même.

Quand j'ai *enfin* remarqué l'opérateur puissance (aujourd'hui, en fait), autant dire que je ne me suis pas senti très malin. Mais bon. :P
Auteur et mainteneur du projet P7 pour calculatrices CASIO, dont ma collection est ici. Également sur Mastodon. J'ai réalisé un bot Mastodon pour le forum de Silicum.
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3419
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par C.Ret »

Je me rends compte que je suis incapable d'écrire deux lignes de code pour les CASIO Graphiques. Si j'ai le temps, il faudra que je m'y mette !

En attendant, voici une première proposition pour HP-41C (en attendant la version pour HP-65) sans aucun module particulier.

Code : Tout sélectionner

001*LBL "MPO80                               .  .  .  s        @@ nbr. de valeurs à éliminer (skip) 
002 1                                        .  .  s  1
003*LBL 00                                   .  .  s  n        @@ Boucle principale, n impair suivant
004  2  +  OCT  1  XEQ 01  RDN VIEW X                          @@ affiche progression en octal 
011  DEC  FC?C 01  GTO 00                                      @@ n en octal non premier      --> suivant 
014  1  XEQ 01  RDN  FC?C 01  GTO 00                           @@ n en décimal non premier    --> suivant
019  DSE Y GTO 00  TONE 1  RTN               .  .  0  n        @@ décrémente le compteur et signal d'arrêt
023* LBL 01                                  .  s  n  f        @@ Test primalité de n par facteur croissants
024    2  +  RCL Y  x<>y  x^2  x>y? SF 01    s  n  n  f²    f  @@  facteur supérieur à /n alors n est premier
031    X<> L  MOD  FS? 01 RTN  x=0? RTN      .  s  n  m     f  @@  facteur multiple ou n premier on sort
037    X<> L  GTO 01  END                    .  s  n  f        @@  boucle du test  
En entre dans la pile le compteur "c" souhaité et la calculette compte tous les nombres octal premiers jusqu'à épuiser le compteur.

Donc, pour avoir le 52-ième nombre octal premier, il faut entrer 51 [XEQ]"MPO80" pour lancer le programme qui s'arrêtera sur l'affichage du 52-ième nombre octal premier. Le signal sonore facilite les éventuelles opérations de chronométrage. Une pression sur [ <- ] revient à l'affiche normal de la pile qui donne la valeur décimale correspondante. Pour faire patienter, le code affiche la progression des nombres en octal.

Le code n'utilise que les registres de la pile. C'est court mais loin d'être rapide car à chaque valeur octale, deux déterminations de primalité sont effectuées (sous-programme XEQ 01). Il faut environ 28 min pour déterminer les 52 premiers.
Le drapeau utilisateur 01 est utilisé pour indiquer un nombre premier.
Seules les nombres impairs sont scannés, on ne peut pas obtenir le premier nombre premier octal 2.o qui est pair.


Le code ci-dessous, issu du premier code, liste (ou imprime) tous les nombres octals premiers :

Code : Tout sélectionner

01*LBL "MPO80P    11 2              21 GTO 00         31 RTN            41 X<> L
02 FIX 0          12 +              22 ARCL X         32 GTO 00         42 MOD
03 "1: 2.O 2.d"   13 OCT            23 "~.d"          33*LBL 01         43 FS? 01
04 AVIEW          14 ARCL X         24 1              34 2              44 RTN
05 2              15 "~.O  "        25 XEQ 01         35 +              45 x=0?
06 1              16 1              26 RDN            36 RCL Y          46 RTN 
07*LBL 00         17 XEQ 01         27 FC?C 01        37 X<>Y           47 X<> L
08 CLA            18 RDN            28 GTO 00         38 x^2            48 GTO 01
09 ARCL Y         19 DEC            29 AVIEW          39 x>y?           49 END
10 "~: "          20 FC?C 01        30 ISG Y          40 SF 01          
Donc voici, la copie de sortie imprimante pour les 60 premiers nombres recherchés (on y trouvera ma réponse à la 52-ième ligne qui est d'ailleurs la même que celle donnée par cakeisalie au début de ce fil :
Image

Bon, c'est assez lent (mais pas interminable), pour la version SHARP PC-1211, je vais utiliser une astuce de mnemonization afin d'accélérer les choses et éviter tous ces boucles de recherche des nombres premiers.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2931
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par zpalm »

Bravo C.Ret pour ton programme sur HP-41C !!

Je vois que depuis dimanche matin tu l’as amélioré à plusieurs reprises. C’est dommage de ne pas garder trace des différentes versions.

Comme toi initialement j’avais pensé utiliser les fonctions OCT et DEC avec le contrôle d’erreur par le flag 25 de la 41C sur la conversion DEC, mais je ne voyais pas comment appliquer ce principe sur la HP 65 dont la fonction de conversion OCT->DEC (f-1 OCT) ne détecte pas les nombres invalides.

Ta dernière version qui ne nécessite plus d’utiliser le flag 25 ouvre la porte à un programme pour la HP-65!
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3419
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par C.Ret »

En fait, j'ai enlevé la version utilisant le flag 25 car en relisant je me suis rendu compte que je n'en avait pas besoin.
La version que j'avais posté était un mixte entre une version détectant les nombres décimaux pouvant être des nombres octals et une verrsion plus évoluée qui se passe de cette étape.

Je l'ai retirer en remplaçant car mon code était erroné : les instruction du flag 25 encadrées l'exécution de l'instruction OCT qui ne crée jamais d'erreur.
C'est uniquement la fonction DEC qui crée une erreur "BAD DATA" si le nombre traité contient des 8 ou des 9. Alors que sont homologue sur HP-65 converti tout de même ces nombres.
Dans la version que j'avais posté dimanche matin, le flag 25 était donc mal utilisé :

Je la remets ici :

Code : Tout sélectionner

001*LBL "MPO80                                .    .    .    c
002 1  ST- Y                                  .    .    c    1
004 LBL 00                                    .    .    c    n
005  2  +  SF 25  OCT  FC?C 25  GTO 00                         
011  1  XEQ 01  RDN  DEC  FC?C 01  GTO 00
017  1  XEQ 01  RDN  FC?C 01  GTO 00
022  VIEW X  DSE Y GTO 01  RTN                .    .    0    n
026* LBL 01                                   .    c    n    f
027    2  +  RCL Y  x<>y x^2  x>y? SF 01      c    n    n    f²       f
034    X<> L  MOD  FS? 01 RTN  x=0? RTN       .    c    n    m        f 
040    X<> L  GTO 01  END                     .    c    n    f
Ainsi que la version de samedi soir (trop tard pour que je la poste) avec quelques labels supplémentaires, labels qui ont disparus afin de miser plus petit :

Code : Tout sélectionner

001 LBL "MPO80					c
002 1					c	0
003 LBL 00				c	n-1
004 1				c	n-1	1
005 +					c	n 		1 
006 SF 25				c	n		
007 OCT  				c	n/o		n
008 FC?C 25  GTO 00			c	n 
010 XEQ 01              		c	o
011 DEC					c	d/n		o
012 FC?C 01  GTO 00			c	n
014 XEQ 01
015 FC?C 01  GTO 00			c	'n
017 DSE Y  GTO 00 
019 RTN

020 LBL 01				c	x
021 2				c	x	2
022 STO L			c	x	2		2
023 LBL 02			c	x	.		f
024 RDN					c	x		f
025 LastX			c	x	f	
026 x^2				c	x	f²		f
027 x>y?  SF 01			
029 FS? 01  GTO 03		
031 RDN  RCL X  RCL L	c	x	x	f
034 MOD				c	x	m
035 x>0?  GTO 02
037 LBL 03			c	x	.
038 RDN					c	x
039 RTN

Cela permet de comprendre comment je fonctionne : je suis plus ou moins bien une idée parfois pas très rigoureuse. Ici typiquement le flag 25 qui avait été imaginé couplé avec l'instruction DEC pour détecter les nombres "non octals" c'est retrouvé aux dernières heures de lucidité du samedi soir utilisé avec l'instruction OCT.
Car entre-temps, ayant pris un bon en-cas à base de truite fumée et de riesling, je me suis dit qu'il était plus simple de parcourir les entiers en décimal, de convertir en octal et de faire les deux tests.

Ce soir, je viens de faire tourner ce principe sur mon SHARP qui n'a pas d'instruction OCT/DEC. Le plus économique est alors de faire quatre boucles imbriquée, une pour les unités, les dizaines, centaine et milliers. Il est alors facile d'avoir le nombre octal et décimal à chaque étape.

Mais alors, pourquoi faire deux tests successifs de primalité. Il est bien plus économique de combiner les deux test en un seul. Comme cela, si l'un ou l'autre des deux nombres est un nombre composé, on économise des boucles de test pour l'autre.

Je vais donc très vite poster les codes correspondant à cette nouvelle approche :)


Code : Tout sélectionner

001 LBL "80MPO                                             .  .  .  n @@ Mémorise argument dans compteur registre 00:
002   STO 00  1  RDN                                       1  .  .  n
005   LBL 00                                               d  .  .  . @@ Boucle incrément DECimal et calcul OCTal
006     R^  2  +  ENTER^  OCT  1                           .  d  o  1
012     LBL 01                                             .  d  o  f @@ Boucle test primalité combiné de DEC et OCT
013       2  +  RCL Y  X<>Y  ST/ Y  x>y? GTO 02            d  o o/f f @@   test positif    --> Lbl 02 
020       X<>Y  FRC  x=0? GTO 00                           d  o  f  0 @@  OCT est composé  --> Lbl 00 suivant
024       RDN  RCL Z  X<>Y  ST/ Y  X<>Y  FRC  x=0? GTO 00  d  o  f  0 @@  DEC est composé  --> Lbl 00 suivant
032       RDN  GTO 01                                      .  d  o  f @@ Boucle test   
034     LBL 02                                             d  o  .  . @@  Affiche OCT premier et décompte registre 00:
035     VIEW Z  DSE 00 GTO 00                              d  .  .  . 
038   R^  TONE 1  END                                      .  .  .  d @@  Met DEC en haut de pile et signal de fin
Comme pour la première version, il faut saisir 51 pour avoir le 52-ième octal premier et 2 n'est pas accessible.
A peine plus long et tellement plus rapide !


Et avec une machine BASIC n'ayant pas de fonction de conversion décimal/octal :

Code : Tout sélectionner

1 F=F+2,P=X/F,Q=Y/F:IF P<F LET N=N+1:PRINT USING "###";N;":";USING "#####";X;" ";USING ;Y:RETURN
2 IF P<>INT P IF Q<>INT Q GOTO 1
3 RETURN
        
4 " " AREAD M:N=0,F=0,X=2,Y=2:GOSUB 1:FOR A=0 TO 7:FOR B=0 TO 7:FOR C=0 TO 7:FOR D=1 TO 7 STEP 2
5 Y=512A+64B+8C+D,X=Y+488A+36B+2C,F=1:IF X>1 GOSUB 1:IF N=M BEEP 1:END
6 NEXT D:NEXT C:NEXT B:NEXT A:END
Dans cette version on saisit n pour DEF-SPC imprime les n premiers nombres octals premiers et leurs homologues décimaux.


Image
Le n°50 manque (bourrage papier dû à une fin de rouleau et un opérateur maladroit).
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3419
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par C.Ret »

Et voici, une version pour HP-65 :

Code : Tout sélectionner

OP-Code   Keys     Stack:                      Registres/Commentaires
00 00              t:   z:   y:   x:      L:
23      LBL
11        A         .    .    .    n                  
33 08     STO 8                                r8: Compteur nombre (seul registre utilisé par DSZ)
01        1         .    .    n    1
35 08     g R↓      1    .    .    n
23      LBL
00       0          d    .    .    .           *** boucle principale parcourt d = décimal
35 09     g R↑      .    .    .   'd
01        1         .    .   'd    1
33 01     STO 1                                r1: Facteur f pour test primalité
61        +         .    .    . 'd+1        1
35 00     g lstx    .    . 'd+1    1        1    
61        +         .    .    .    d        2
41        ENTER↑    .    .    d    d
31        f
00        →OCT      .    .    d    o        d   (o = valeur octal correspondant à d)
23      LBL
02       2          .    .    d    o           *** boucle test primalité par division par succession de f
41        ENTER↑    .    d    o    o
41        ENTER↑    d    o    o    o
02        2         d    o    f    2
33        STO
61        +                         
01        1         d    o    o    2           r1: Addition dans registre r1   f <-- f+2
45        Clx
34 01     RCL 1     d    o    o    f
81        ÷         d    d    o  o/f        f
35 00     g lstx    d    o  o/f    f     
35        g                                   *** test primalité f suffisament grand, o est donc premier
24        x>y?
21        GTO
03        3         d    o    .    .          *** o et d sont premiers  ==> décompte nombre   
45        Clx       d    o  o/f    0
35 07     g x↔y     d    o    0  o/f
32        f-¹
83        INT       d    o    0 .ppp      o/f
35        g                                   *** test multiplicité de o avec f
23        x=y?
22        GTO
01        1         d    .    .    .          *** o est composé        ==> d suivant           
71        ×         d    d    o    0   .pppp
35 09     R↑        d    o    0    d
61        +         d    d    o    d
34 01     RCL 1     d    o    d    f
81        ÷         d    d    o  d/f       f
32        f-¹
83        INT       d    d    o .qqq     d/f
00        0         d    o .qqq    0
35        g                                   *** test multiplicité de d avec f
23        x=y?
22        GTO
01        1         d    .    .    .          *** d est composé      ==> d suivant
35 09     R↑        o    .    .    d
35 09     R↑        .    .    d    o
22        GTO
02        2                                   *** continue boucle test primalité ==> f suivant
23      LBL
03       3          d    o    .    .          
35        g
83        DSZ                                 *** décrémente compteur de nombre
22        GTO
01        1        d    .    .    .
35 08     R↓        .    d    o    .
35 08     R↓        .    .    d    o
24        RTN                                 *** fin affiche nombre octal en haut de pile
Je n'ai pas cette machine sous la main, merci de votre indulgence. en cas d'erreur, des OP-Codes notamment, merci de me le signaler.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2931
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par zpalm »

J'ai essayé le programme HP 65 sur ma tablette avec go65c, mais ça ne marche pas. Il ne passe jamais sur l'instruction DSZ et tourne en boucle.

Par contre je me suis largement inspiré de ton programme 41C pour améliorer le mien qui utilise l'instruction PRIME? du module SandBox:

Code : Tout sélectionner

01 LBL “MPO80
02 1 ENTER
04 LBL 01 RDN 2 +             .  .  s  n       //  nombre suivant
08 ENTER PRIME? X<0? GTO 01   .  s  n  n       // decimal premier? non, nombre suivant
12 OCT PRIME? DSE Z GTO 01    .  s  n  o       // octal premier? non, nombre suivant si ce n'est pas la fin
16 END
51 XEQ MPO80 s'exécute en 3mn 31s, contre 7mn 28s pour ma version initiale:

Code : Tout sélectionner

001*LBL MPO80
002 1
003*LBL 00
004 2 +
006 SF 25 DEC FC?C 25 GTO 00
010 PRIME? GTO 01 X<>L OCT GTO 00
015*LBL 01 OCT PRIME? GTO 02 X<>L GTO 00
021*LBL 02 DSE Y GTO 00
024 RTN
Pour la première fois je n'ai pas réussi à faire une version WP 34S qui soit plus courte que la version 41C car la conversion décimal-octal n'est pas traitée de la même façon. Voici ma meilleure version. L'avantage c'est qu'elle gère le nombre 2, il faut donc le lancer par 52 A qui s'exécute en 13s:

Code : Tout sélectionner

01 LBL A
02 LocR 001 STO.00 CLSTK                 .  .  0  .          // initialisation, 1 registre local (R.00)
05 RDN                                   .  .  .  n
06 NEXTP                                 .  .  .  n          // nombre premier decimal suivant
07 CL⍺ BASE 08 ⍺IP X DECM 0              .  .  n  0          // conversion octal: nombre octal dans Alpha
12 ⍺→x x=0? SKIP 006                     .  n  o  c          // fin de la conversion decimal->octal ?l
15 #48 – x<>y SDL 001 + BACK 008         .  .  n  o          // conversion decimal->octal un digit à la fois                          
21 RDN PRIME? DSZ.00 BACK 019            .  .  n  o          // est-ce un octal premier? non, nombre suivant
25 END
Les instructions BASE 08 au pas 08 et DECM au pas 10 sont obtenues respectivement par [g] [+/-] et [f] [RCL].

Et pour finir une petite version sur HP Prime qui s'exécute en 0.4s:

Code : Tout sélectionner

EXPORT MPO80(N)
BEGIN
LOCAL n,o,p;
WHILE(n<N) DO
  p:=nextprime(p);
  IFERR o:=B→R(EXPR("#"+p+"o")) THEN ELSE n:=n+isprime(o) END;
END;
p;
END ;
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3419
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par C.Ret »

Je suis très impressionné par la version en 16 instructions utilisant l'instruction de saut conditionnel PRIME? du module SANDBOX, l'enchainement OCT PRIME? DSZ Z GTO 01 et surtout l'astuce du X>0? entre PRIME? et GTO 01 pour continuer si la valeur décimale est un nombre première.
Si ça c'est pas de l'optimisation et du misez petit !!!
Il m'a fallu un peu de temps pour me rendre compte du rôle du x>0? : :tongue:

Et tout cela sans programmation synthétique ?



Par ailleurs, j'ai moi aussi tentez une version sur HP Prime en utilisant l'instruction R->B. Mais elle ne fonctionne pas comme je le souhaiterai.
En fait ,les instructions R->B ressemble à celle présentent sur les HP28/48/50 mais sans la souplesse de objets traité dans la pile des RPN.
Alors, là où une conversion décimal/octal/texte/décimal prend deux ou trois instructions simple, cela devient un calvaire sur l'HP Prime et perd tout l'intérêt de cette voie pour un MPO.

Autant , utiliser les boucles FOR FRON TO DO enchainée comme sur les BASIC de 1983.

Donc, 'utilisation de la structure IFERR THEN ELSE END est effectivement bien plus efficace (et me fait un peu penser à l'utilisation du drapeau 25 des HP41C !)
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2931
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par zpalm »

Une petite optimisation de la version WP 34S: 3 pas de moins.

Code : Tout sélectionner

01 LBL A
02 c#048 STO I                                  .  s  0  48         // initialisation
04 RDN NEXTP                                    .  .  s  n          // nombre premier decimal suivant
06 CL⍺ BASE 08 ⍺IP X DECM c#000                 s  n  0  0          // conversion octal: nombre octal dans Alpha
11 + SDL 001 ⍺→x RCL-I x>=0? BACK 005           s  n  o  c          // fin de la conversion decimal->octal ?                          
17 RDN SDR 001 PRIME? DSZ Z BACK 017            .  s  n  o          // est-ce un octal prime? non, nombre suivant
22 END
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: Misez p'tit Optimisez n°80 : Nombres premiers en base 10 et 8

Message par Gilles59 »

Bonsoir !
zpalm a écrit : 24 juin 2017 08:26 Et pour finir une petite version sur HP Prime qui s'exécute en 0.4s:

Code : Tout sélectionner

EXPORT MPO80(N)
BEGIN
LOCAL n,o,p;
WHILE(n<N) DO
  p:=nextprime(p);
  IFERR o:=B→R(EXPR("#"+p+"o")) THEN ELSE n:=n+isprime(o) END;
END;
p;
END ;
Ce qui traduit "mot pour mot" en RPL HP50 donne :

Code : Tout sélectionner

« 0  → N n
  «
   1 
   WHILE 'n<N' REPEAT
    NEXTPRIME
    IFERR "#" OVER + "o" + STR→ B→R THEN DROP ELSE ISPRIME? 'n' STO+ END
   END
  »
»
On reconnaît l'héritage du jeu de commande de la PRIME sur le RPL ;D
Casio FX-502P /602P / 603P / FX180P+ / FX4000P / TI57 / TI66 / TI74 Basicalc / TI95 Procalc / HP12C / HP15C LE / DM41L / HP 30B / HP39GII / HP 48SX USA / 49G / 49g+ / 50G / 50G NewRPL / HP Prime / Oric 1 / Amstrad CPC 6128+ CM14 et MM12 / Alice 32
Répondre

Retourner vers « Tous les Pockets »