Misez p'tit Optimisez n°53 : la suite de Syracuse

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
bernouilli92
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5259
Enregistré le : 21 nov. 2012 13:03
Localisation : Ile de France

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par bernouilli92 »

Marge a écrit :"WHILE ROT DUP 1"

C'est ça qui m'handicape dans le RPL... je comprends l'anglais mais rien n'y fait.
Ce n'est pas très compliqué, en rpl il y a une pile comme en rpn sauf qu'elle n'est pas limité à 4 éléments.
Le while repeat fonctionne de la maniere suivante :
Le while donne le debut de la boucle, le end la fin de la boucle et le repeat constitue le test.
Le test revient à enlever l'element au haut de la pile et de tester sa valeur, si elle vaut 0 le test est faux sinon il est vrai. L'instruction > effectue un test de superiorité entre les deux premiers éléments de la pile.
DUP 1 > revient à tester si le nombre sur le haut de la pile est supérieur à 1, le DUP est là pour préserver ce nombre, le test s'effectue sur une copie.
Pour résumer, WHILE ROT DUP 1 > REPEAT .... END revient à exécuter ce qu'il y a entre le REPEAT et le END tant que le 3ème élément de la pile est strictement supérieur à 1.
Note : après le test, l'élément en position 3 se retrouve en position 1
HP, Casio, Sharp, Psion, quelques TI et divers autres
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2930
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par zpalm »

@C.Ret: j'ai quasiment écrit le même programme sur ma 41C!!
Tu peux économiser un pas en supprimant le ENTER du pas 12 et remplaçant aux pas 16 et 25 les instructions Clx et RDN par LastX.
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°53 : la suite de Syracuse

Message par C.Ret »

Marge a écrit :"WHILE ROT DUP 1 > "
C'est ça qui m'handicape dans le RPL... je comprends l'anglais mais rien n'y fait.

Il faut se dire, le RPL c'est du RPN et dessiner le contenu de la pile à chaque pas :

Code : Tout sélectionner

COMMANDES:         4:   3:   2:   1:     TEST/BOUCLE
«                                  n                   @ Initialise MAX et TOF
  DUP                         n    n
  0                      n    n    0

                         n    m    t                   @ Dans l'ordre n m et t !
  WHILE                  
     ROT                 m    t    n
     DUP 1 >                             n>1 ?         
  REPEAT                 m    t    n                   @ Boucle tant que n>1 
    IF 2 /               m    t  n/2
       DUP FP       m    t  n/2    f                   @ avec f=FRAC(n/2)
    THEN                                 f<>0 ?        @ si était n impair
                         m    t  n/2
       6 * 1 +           m    t 3n+1                   
    END
                         m    t    n'                  @ Où n' est 3n+1 ou n/2 selon la parité de n
                                                  
    ROT                  t    n'   m                   @ Met m et n' en vis à vis  
    OVER             t   n'   m    n'
    MAX                  t    n'   m'                  @ Remet à jour MAX   m'=MAX(m,n')

    ROT 1 +              n'   m'   t'                  @ Incrémente TOF   t'=t+1
  END                                                  @   La pile étant à nouveau dans l'ordre { n m t }, on boucle
  
                         m    t    1
  DROP                        m    t                   @ Laisse dans la pile MAX et TOF
»     
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°53 : la suite de Syracuse

Message par C.Ret »

zpalm a écrit :@C.Ret: j'ai quasiment écrit le même programme sur ma 41C!!
Tu peux économiser un pas en supprimant le ENTER du pas 12 et remplaçant aux pas 16 et 25 les instructions Clx et RDN par LastX.
Effectivement, j'ai d'ailleurs peu de temps après avoir posté modifier cette partie du code qui évite d'ailleurs complètement la partie sous le LBL 02 qui devient inutile.
L'astuce consiste à décaler les trois variables { t m n } sur les registre t:z:y: au début (et fins) de la boucle 00 !
bernouilli92 a écrit :[...]Note : après le test, l'élément en position 3 se retrouve en position 1
C'est une remarque fort pertinante qui, l'air de rien, démontre qu'en RPL, il y a aussi une forme d'instruction EXIT/BREAK.

En effet, ma façon d'utiliser le ROT dans la clause d'intialisation du WHILE ... REPEAT ... END revient en fait à utiliser un EXIT dans les boucle DO ... LOOP chère à d'autres languages. Tout ce qui est entre le WHILE et le END est répété, y compris les instructions de mise en place des éléments (c'est le cas du ROT) ou d'autres (par exemple un affichage, etc...).
C'est la position du REPEAT qui donne la position de la sortie (du EXIT ou BREAK en quelque sorte).

Code : Tout sélectionner

PROGRAM Syracuse ;
VAR  
   n,m : REAL ;
   t : INTEGER ;
BEGIN
  READ n
   m := n ;
   t := 0 ;
   WHILE (n>1) DO
     BEGIN
      n := n/2 ;
      IF n<>INT(n) THEN 
          BEGIN 
             n := 6*n+1 ;
             IF n>m THEN m := n ;
          END ;
      t := t+1 ;
     END ;
  WRITELN( m , t ) ;
END.
Modifié en dernier par C.Ret le 30 mars 2014 19:39, modifié 1 fois.
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
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°53 : la suite de Syracuse

Message par ledudu »

Vu que y'a des piles dans mon Psion...

Code : Tout sélectionner

rem procédure principale : input du n0>0 dans une boite de dialogue et boucle sur la suite tant que Un<>1
PROC mpo53:
   local n,tdv,alt
   init::
   dINIT "Misez p'tit optimisez n°53"
   dFLOAT n,"Donnez la valeur initiale:",1,1E20
   DIALOG
   CLS
   PRINT "Valeur initiale     : " ",n
   tdv=0
   alt=n
   WHILE n<>1
       IF frac:(n/2)=0
            n=n/2
       ELSE
            n=3*n+1
            alt=max(alt,n)   
       ENDIF
       tdv=tdv+1
   ENDWH
   PRINT "Temps de vol       : ",tdv
   PRINT "Altitude maximale  : ",alt
   PAUSE 0
   GOTO init
ENDP
rem Procédure qui extrait la partie fractionnaire
PROC frac:(r)
    RETURN r-INT(r)
ENDP
En modifiant un peu ce code, on peut lui faire chercher les plus grands temps de vol et altitude :
n=20 895 - altitude = 50 143 264
n=26 623 - altitude = 106 358 020
n=31 911 - altitude = 121 012 864
n=60 975 - altitude = 593 279 152
n= 34 239 - temps de vol=310
n= 35 655 - temps de vol=323
n= 52 527 - temps de vol=339
Avatar du membre
Marge
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 6186
Enregistré le : 01 oct. 2008 14:39
Localisation : En bas, tout au fond à gauche.

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par Marge »

C.Ret a écrit :
Marge a écrit :"WHILE ROT DUP 1 > "
C'est ça qui m'handicape dans le RPL... je comprends l'anglais mais rien n'y fait.

Il faut se dire, le RPL c'est du RPN et dessiner le contenu de la pile à chaque pas :

Code : Tout sélectionner

COMMANDES:         4:   3:   2:   1:     TEST/BOUCLE
«                                  n                   @ Initialise MAX et TOF
  DUP                         n    n
  0                      n    n    0

                         n    m    t                   @ Dans l'ordre n m et t !
  WHILE                  
     ROT                 m    t    n
     DUP 1 >                             n>1 ?         
  REPEAT                 m    t    n                   @ Boucle tant que n>1 
    IF 2 /               m    t  n/2
       DUP FP       m    t  n/2    f                   @ avec f=FRAC(n/2)
    THEN                                 f<>0 ?        @ si était n impair
                         m    t  n/2
       6 * 1 +           m    t 3n+1                   
    END
                         m    t    n'                  @ Où n' est 3n+1 ou n/2 selon la parité de n
                                                  
    ROT                  t    n'   m                   @ Met m et n' en vis à vis  
    OVER             t   n'   m    n'
    MAX                  t    n'   m'                  @ Remet à jour MAX   m'=MAX(m,n')

    ROT 1 +              n'   m'   t'                  @ Incrémente TOF   t'=t+1
  END                                                  @   La pile étant à nouveau dans l'ordre { n m t }, on boucle
  
                         m    t    1
  DROP                        m    t                   @ Laisse dans la pile MAX et TOF
»     
Merci pour ces efforts de pédagogie, C.Ret.

Désolé d'intervenir si tard (mais tout le monde est couché :lol: ), c'est que je ne comprends pas la 4ème ligne - après l'introduction du 0 - : il manque une commande pour obtenir tous ces n, m et t, non ?
3 hommes, 3 demis, un 3a... Magnéto, Serge !

Quelques-uns de mes petits programmes pour machines Hewlett-Packard :
15C : Knight's Tour ;
29C : (k-)Permutations, Combinations, Linear Regression and Pseudo-random number ;
34C : Hanoi Towers - Automatic & Manual resolutions ;
67
__: A L I E N .

« Boris », c'était juste Maurice enrhumé.
Avatar du membre
Forthman
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 164
Enregistré le : 03 juin 2009 06:51
Localisation : Castelsarrasin (82)

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par Forthman »

en fait T=0 au début :wink:


moi j'adore le RPL, c'est presque comme du Forth sauf qu'ils ont "retourné" quelques structures de
contrôle, sûrement pour simplifier, et du coup c'est l'inverse :?

par exemple :
RPL : IF a 2 == THEN (partie exécutée si a=2) END (suite du progr)
FORTH : a 2 = IF (partie exécutée si a=2) THEN (suite du progr)

d'ailleurs, on peut même écrire en RPL : a 2 IF == THEN (partie exécutée si a=2) END (suite du progr) :mrgreen:
Avatar du membre
bernouilli92
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5259
Enregistré le : 21 nov. 2012 13:03
Localisation : Ile de France

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par bernouilli92 »

Effectivement en RPL l'instruction IF ne sert à rien (et ne fait rien).
Mais cela a l'avantage d'être un peu plus clair, ce qui est déroutant en forth c'est que l'instruction THEN arrive quand tout est déjà fini ;-)
Si je devait réinventer le forth, je mettrai deux instructions : IFTHEN et END (ou ENDIF)
HP, Casio, Sharp, Psion, quelques TI et divers autres
Avatar du membre
Forthman
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 164
Enregistré le : 03 juin 2009 06:51
Localisation : Castelsarrasin (82)

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par Forthman »

Je trouve au contraire le forth plus logique car tout est inversé
1 1 + : le "+" agit sur les éléments de gauche
1 = IF : la condition est à gauche
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°53 : la suite de Syracuse

Message par C.Ret »

Marge a écrit :[...]c'est que je ne comprends pas la 4ème ligne - après l'introduction du 0 - : il manque une commande pour obtenir tous ces n, m et t, non ?
Comme l'a très bien dit Forthman, il y a à la quatrième ligne le contenu général de la pile en début de boucle (dans l'ordre n, m et t ) et sur la troisème les valeurs initiales de ces trois variables.

En fait au premier passage, n=n (donnée utilisateur), m=n (j'initie le maximale à n au cas où il n'y aurait que des pairs) et t=0 (temps de vol initial).

Plus loin, j'utilise une autre convention où je désigne par des primes les valeurs suivantes ou précèdantes... A force, j'ai mes petites habitudes et j'oublie d'expliquer. Par exemple 'n, n et n' désignent les valeurs sucessives d'une même variable n !


Forthman a écrit :Je trouve au contraire le forth plus logique car tout est inversé
1 1 + : le "+" agit sur les éléments de gauche
1 = IF : la condition est à gauche
Dit comme cela ça parait tellement plus simple !
J'en oublie presque la façon dont tout cela m'a été enseigné et les longues heures à saisir la diffèrence entre une fonction, une commandes, des opérantes, des instructions, une structure, etc...

C'est vrai que le IF en RPL ne sert à rien sauf que s'il on ne le met pas le parseur crie au scandale lors de la validation du code; et donc pas moyen d'enregistrer un programme sans les IF.

Quand à sa position, on peut le mettre presque où l'on veut : même a 2 == IF THEN ... END (/b] est authorisé.

Par contre, en cas d'imbrication, sa position devient très importante :
Que renvoi ce code si je saisi la valeur 1 ? Puis la valeur 2 ? Ou la 3 ?

Code : Tout sélectionner

« IF 1 
  IF ==
  THEN 1 END
  THEN 2 
  ELSE 3 END
»
That question the is !
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.
caloubugs
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 434
Enregistré le : 05 juin 2014 22:23
Localisation : Dans le Gâtinais avec les abeilles, près de Fontainebleau

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par caloubugs »

Ah ben mince, je tombe sur ce sujet sur lequel j'ai fait pas mal de comparos entre mes machines.
Je posterai ce que j'ai fait en fin de semaine (pas chez moi :( merci le boulot).

J'ai fait d'ailleurs des tests sur les 3 modes du HP71B : basic pur, basic + forth et basic + assembleur.

De mémoire, en dessous de 100000, c'est 77031 qui a le plus long temps de vol (350). Mais j'avais fait un programme sur PC qui avait tout calculé jusqu'à 1 milliard (et je crois qu'on ne dépassait pas 1000 en temps de vol).

Sur 77031, la HP71B faisait dans les 40 secondes en basic, 25 en forth et 8 centièmes de seconde en assembleur !

Le casio Z-1GR : 6 secondes en basic et 3 secondes en C (bon là, c'est tout frais, j'ai la bécane depuis samedi - et il me semble avoir vu mon vendeur très sympa sur ce forum !).

C'est un bon petit benchmark, facile à développer (même si pour l'assembleur du HP71B, j'ai repris celui disponible dans les LIF).
RetroGeek, mais pas que...
HP : 15C, 41CV, 48GX, 71B, 75C Canon X-07 Sharp PC 1403H, PC1500A, PC1600, PC-G850V Texas : CC40, 66, 74, 95, 92 Casio : PB-700, PB-1000, Z-1GR Psion 5mx, mais pas que...
Céline
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 169
Enregistré le : 23 mars 2014 13:11

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par Céline »

Cool ça.
J'attends ça, même si je me limiterai au basic basique car le reste m'est complètement étranger.
TI-30 Galaxy
fx-180P, fx-4000P
HP 11c, 12c, 12c le, 15c, 15c le
HP 32s, 32s ii, 42s, 17b ii, 30b, 35s
HP 28s, 48s, 48sx, 48g, 50g, prime
caloubugs
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 434
Enregistré le : 05 juin 2014 22:23
Localisation : Dans le Gâtinais avec les abeilles, près de Fontainebleau

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par caloubugs »

En pleine insomnie dans mon hôtel à Nevers (je suis sûr que vous m'enviez 8O ), boum, je repense à ULAM (que je préfère à Syracuse, en hommage à ce mathématicien qui lors d'une réunion où il s'ennuyait, s'est mis à penser à une spirale qui nous amènera à ce sujet)...

Il y a deux choses qui manquent dans nos programmes :
1 : on optimise au niveau taille, alors que sur les poquettes (et quand j'étais étudiant en informatique), l'optimisation devrait d'abord se faire sur le temps d'exécution (et derrière le nombre de cycles d'horloge). Surtout quand on a du calcul itératif. Ce n'est qu'après et pour la beauté du geste qu'on cherche l'optimisation en taille de code. Or, je pense qu'on y est pas sur la rapidité.
2 : il manque un contrôle dans tout ça pour garantir la fiabilité du calcul (on ne maîtrise pas l'altitude) : on peut dépasser le nombre de chiffres significatifs des machines et fausser le résultat.

J'ai fait un petit programme sur mon émulateur Go71b :

Code : Tout sélectionner

10 s=0 @ input 'Nombre : ';n @ t=time
20 s=s+1 @ if mod(n,2)=0 then n=n/2 else n=n*3+1
30 if n>1 then 20
40 t=time-t @ print 'Vol : ';s;' Temps : ';t
Sur l'émulateur (en simulant approximativement la vitesse réelle de la HP71B), j'arrive pour N=77031 à 15,09 secondes (c'est en gros l'algorithme suivi par tous). J'ai l'impression que l'émulateur va un peu vite quand même :mrgreen:
Or, quand on multiplie par 3n et qu'on ajoute 1, on arrive toujours sur un nombre pair (puisqu'on part alors d'un nombre impair), du coup je modifie la ligne 20 en :

Code : Tout sélectionner

20 s=s+1 @ if mod(n,2)=0 then n=n/2 else n=(n*3+1)/2 @ s=s+1
On évite alors un contrôle de parité inutile : résultat 12,07 secondes (pas rien quand même ! :? ).
Il faut faire attention également à regrouper un maximum d'instruction sur une ligne en Basic, puisqu'étant interprété, il faut justement faire un minimum appel à l'interpréteur (chaque saut de ligne se paie en millisecondes).
La recherche de rapidité nécessite aussi de connaître à fond les possibilités offertes par le langage résident (où justement on se rend compte à ce moment là de la puissance du basic embarqué). Comme par exemple ici, la possibilité d'avoir la fonction modulo (pour le calcul de reste de division) présente sur la 71B (les casio aussi je crois) alors que sur d'autres machines (comme les sharp :roll: ) c'est absent et il faut faire des calculs coûteux en ressources CPU.

Reste à trouver le meilleurs endroit pour mettre le contrôle de dépassement de capacité (qui va nous manger du temps). Normalement avant la multiplication (par exemple si on a une précision à 12 chiffres comme sur la 71B, il faut vérifier que n<333333333333 avant de faire n=3n+1), On se retrouve avec deux If then else imbriqués avec la limitation en taille de la ligne. Gasp, va falloir tester et répartir tout ça sur plusieurs lignes pour voir les meilleurs choix.

Avis aux amateurs ! :pirat:

(Edit : mon code en exemple est faux pour n=1, car je commence par faire le calcul avant de faire le test de l'égalité à 1. C'était pour l'exemple d'optimisation, et bon, l'insomnie est finie, puisqu'il faut que je parte au taf :cry: , donc pas le temps de modifier tout ça pour le moment)
RetroGeek, mais pas que...
HP : 15C, 41CV, 48GX, 71B, 75C Canon X-07 Sharp PC 1403H, PC1500A, PC1600, PC-G850V Texas : CC40, 66, 74, 95, 92 Casio : PB-700, PB-1000, Z-1GR Psion 5mx, mais pas que...
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2930
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par zpalm »

caloubugs a écrit : Or, quand on multiplie par 3n et qu'on ajoute 1, on arrive toujours sur un nombre pair (puisqu'on part alors d'un nombre impair), du coup je modifie la ligne 20 en :

Code : Tout sélectionner

20 s=s+1 @ if mod(n,2)=0 then n=n/2 else n=(n*3+1)/2 @ s=s+1
Bien vu!

Si j’applique cette optimisation sur mon programme pour WP 34S, il suffit de remplacer la ligne

Code : Tout sélectionner

 016 BACK 008
Par:

Code : Tout sélectionner

 016 INC Y
Pour mesurer le gain de temps j’ai du enchainer 10 appels au programme car un seul appel faisant moins de 10 TICKS la précision de la mesure n’était pas suffisante.
Donc pour 10 fois N=77031 il fallait 103 TICKS avec la version initiale et seulement 83 TICKS avec la version modifiée ce qui donne un gain de 20% sans changer la taille du programme.

Le même type d’optimisation peut être appliqué sur mon programme pour HP Prime, le temps d’exécution pour N=77031 passe de 0.189s à 0.131s après optimisation, soit 30% de mieux!
Image Image Image
A gauche la version initiale du programme; au centre la version optimisée; à droite la mesure du temps d'exécution des deux versions.
caloubugs
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 434
Enregistré le : 05 juin 2014 22:23
Localisation : Dans le Gâtinais avec les abeilles, près de Fontainebleau

Re: Misez p'tit Optimisez n°53 : la suite de Syracuse

Message par caloubugs »

zpalm a écrit : Image
Cool ! J'aime bien ta version optimisée sur la prime avec le code de division implémenté une seule fois.

Sur Emu71 j'arrive à 14,41s en intégrant le contrôle de limite avec le code suivant (contre 13,2 s sans) :

Code : Tout sélectionner

10 S=0 @ INPUT 'Nombre : ';N @ T=TIME
20 IF N=1 THEN 40 ELSE IF N>333333333332 THEN 50 ELSE IF MOD(N,2)=1 THEN N=N*3+1 @ S=S+1
30 N=N/2 @ S=S+1 @ GOTO 20
40 T=TIME-T @ PRINT 'Vol : ';S;' Temps : ';T @ END
50 PRINT 'Depassement capacite'
Mais en faisant moins joli (redondance du code de division) je retombe à 12,55 s :

Code : Tout sélectionner

10 S=0 @ INPUT 'Nombre : ';N @ T=TIME
20 IF N=1 THEN 50 ELSE IF N>333333333332 THEN 60
30 IF MOD(N,2)=1 THEN N=(N*3+1)/2 @ S=S+2 @ GOTO 20
40 N=N/2 @ S=S+1 @ GOTO 20
50 T=TIME-T @ PRINT 'Vol : ';S;' Temps : ';T @ END
60 PRINT 'Depassement capacite'
Reste à intégrer l'altitude max pour respecter le cahier des charges ! Et là je ne rigole plus car ma ligne 30 fait deux itérations en une. Je joue avec pour voir :

Code : Tout sélectionner

10 S=0 @ A=0 @ INPUT 'Nombre : ';N @ T=TIME
20 IF N=1 THEN 50 ELSE IF N>333333333332 THEN 60
30 IF MOD(N,2)=1 THEN N=(N*3+1)/2 @ S=S+2 @ A=MAX(A,N*2) @ GOTO 20
40 N=N/2 @ S=S+1 @ GOTO 20
50 T=TIME-T @ PRINT 'Vol : ';S;' Alt : ';A;' Tps : ';T @ END
60 PRINT 'Depassement capacite'
Résultat : Vol : 350 Alt : 21933016 Temps : 14.45

Et sans la redondance de calcul (pas de *2 dans l'appel à la fonction MAX(), mais un appel systématique à la ligne 40 : ça va se payer sûrement !

Code : Tout sélectionner

10 S=0 @ A=0 @ INPUT 'Nombre : ';N @ T=TIME
20 IF N=1 THEN 50 ELSE IF N>333333333332 THEN 60
30 IF MOD(N,2)=1 THEN N=N*3+1 @ S=S+1 @ A=MAX(A,N)
40 N=N/2 @ S=S+1 @ GOTO 20
50 T=TIME-T @ PRINT 'Vol : ';S;' Alt : ';A;' Tps : ';T @ END
60 PRINT 'Depassement capacite'
Bingo : Vol : 350 Alt : 21933016 Temps : 15.59

Le meilleur code est donc (pour le moment !!) le précédent...
RetroGeek, mais pas que...
HP : 15C, 41CV, 48GX, 71B, 75C Canon X-07 Sharp PC 1403H, PC1500A, PC1600, PC-G850V Texas : CC40, 66, 74, 95, 92 Casio : PB-700, PB-1000, Z-1GR Psion 5mx, mais pas que...
Répondre

Retourner vers « Tous les Pockets »