3344 résultats trouvés

par C.Ret
04 nov. 2014 20:41
Forum : Tous les Pockets
Sujet : Misez p'tit, optimisez n°60 : Calculons Pi comme Viète
Réponses : 143
Vues : 87556

Re: Calculons Pi comme Viète

bernouilli92 a écrit :Voici ma proposition en RPL :

Code : Tout sélectionner

<< 
  2 0 
  1 9 START 
    2 + SQRT 2 OVER / ROT * SWAP
  NEXT DROP
>>
Excellent, j'ai même eut du mal à comprendre.

J'ai dû créer une fonction SQRT pour mieux analyser est comprendre que le produit était fait dans le sens inverse :
... * 2/√(√(√2+2)+2) * 2/√(√2+2) * 2/√2 * 2


Pour ceux qui aimerait refaire pas à pas le calcul, je préconise d'utiliser la fonction SQRT suivante :

Code : Tout sélectionner

« → x « '√a' 2 x EXSUB » »
Cette fonction a l'avantage de ne pas évaluer la racine et d'utiliser l'affichage algébrique des RPL. Ainsi 2 SQRT s'affiche '√2' ce qui est bien plus lisible pour comprendre.


Maintenant que j'ai compris, je peux MPOiser le code de notre ami : j'en profite pour le para-métriser, le nombre d'"itérations" étant au niveau 1: de la pile, utiliser le code suivant pour obtenir l'estimation de PI par François Viète correspondante :

Code : Tout sélectionner

« 0 → n b
  « 2
    1 n START
       2 b 2 + √ DUP 'b' STO / *
    NEXT » » 
C'est le même principe que celui de notre ami Bernouilli mais en utilisant les registres sauvegardés (l'option LAST doit donc être activée sur son HP28/48/50) ce qui permet :
* d'éviter les mouvements de la pile
* faire le produit dans le sens de la formule donnée par Gilles59 (même si cela ne change rien numériquement - cela évite juste le ROT)
* le DROP final n'est plus nécessaire pour vider la pile du "pré-calcul de l'itération suivante" car la calculette laisse bien cachée dans son ventre le contenu des registres de la fonction LAST.

Par contre, il n’évite pas la répétition de tous ces 2, bien trop nombreux à mon avis pour un programme sérieusement optimisé.

La version non-paramétrique s'écrie :

Code : Tout sélectionner

 « 0 → b
  « 2
    1 9 START
       2 b 2 + √ DUP 'b' STO / *
    NEXT » » 
Juste histoire de comptabiliser les 1/2-octets, octets ou nombre de pas je ne sais pas comment faire efficacement sur mon HP-28S

P.S.: j'ai de plus en plus de mal à battre les RPL-istes de ce forum. Je rouille ??

J'oubliais de poster la version pour SHARp PC-1211 :

Code : Tout sélectionner

1:"V" AREAD N : B=0 : P=2 : FOR I=1 TO N : B=√(B+2) : P=2P/B : NEXT I : PRINT N,P : END
par C.Ret
26 oct. 2014 20:46
Forum : Tous les Pockets
Sujet : Gazette N° 4 - PUBLIÉE !!!
Réponses : 138
Vues : 75238

Re: Gazette N° 4 - PUBLIÉE !!!

remy a écrit :au sujet du concours Le compte est bon., je ne comprends pas bien cette phrase :
Les fonctions mathématiques autorisées sont int, frac, +, -, x et :.
Je suis ok sur les 4 opérations mais le INT et le FRAC, je ne vois pas ....
ledudu a écrit :@bernouilli : oui
@remy : Tu n'es pas obligé de les utiliser

Aïeh Aïeh, je suis parti sur un set de fonctions plus étendues : + , - ,×, /, INT et FRAC, mais aussi √n , n! , n² ou n³ et exponentiation x^n .

J'ai juste exclu pour le moment les fonctions log ou sin et cos pensant que des fonctions transcendantales, pour des calculs d'entiers vont très très très peu servir.

Par contre, les fonctions ou ainsi que la factorielle FACT ou PERM et COMB les calculs de combinasons et permutations peuvent-elles faire partie du lot ?

Mais bon quelle est la règle ? Pour calculer un carré je dois utiliser le nombre et le nombre 2, ou deux fois le nombre (x² = x * x ) ?
par C.Ret
17 oct. 2014 22:43
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°53 : la suite de Syracuse
Réponses : 169
Vues : 161468

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

Bonsoir,

A mon humble avis, il y a trop de divisions par deux dans ce code.
On doit pouvoir obtenir quelque chose de plus efficace en ne réalisant qu'une seule division à chaque boucle :
Par ailleurs, les variables locales n et t ne sont utilisées qu'une seule fois dans le programme, je préfère utiliser la pile.

Par ailleurs, et comme le ne va pas manquer de le remarquer les lecteurs attentifs de ce forum, ce programme ne renvoit pas la valeur correcte de MAX pour les n de la forme 2^p !

Code : Tout sélectionner

« TICKS SWAP DUP 2 / 0                   @ Initialise Ticks, TOF et MAX
  WHILE ROT DUP 1 >                      @ Boucle jusqu'à obtenir 1
  REPEAT
     2 /                                 @ calcule n/2
     IF DUP FP 
     THEN
        3 * .5 +                         @ n impair suivant est (3n+1)/2
        ROT OVER MAX                     @ Remet à jour MAX
        ROT 2                            @ Incrémente deux fois TOF
     ELSE 
        ROT                              @ ne remet pas à jour MAX
        ROT 1                            @ Incrémente TOF une fois seulement
     END
     +
  END
  DROP SWAP 2 *                          @ Laisse dans la pile TOF et MAX (corrigé x2)
  TICKS 4 ROLL - B->R 81.92 / IP 100 / » @ Affiche le temps en s

Evidemment, cette version fait moins de tours de piste que celle que j'ai proposée au début de ce fil car à chaque nombre impair, elle réalise systèmatiquement la division par deux en divisant ainsi le nombre de boucles effectuées. Mais le code obtenu contient toujours des répétitions et en particulier des mouvements de pile inutiles.
Je ne suis pas sûr que cela soit réellement aussi efficace que le code suivant plus compact :

Code : Tout sélectionner

« TICKS SWAP DUP 0                        @ Initialise Ticks,MAX et TOF
  WHILE ROT DUP 1 >                       @ Boucle jusqu'à obtenir 1
  REPEAT
    IF 2 / DUP FP THEN 6 * 1 + END        @ Calcule terme suivant de la suite
    ROT OVER MAX                          @ Remet à jour MAX
    ROT 1 +                               @ Incrémente TOF
  END
  DROP                                    @ Laisse dans la pile MAX et TOF
  TICKS 4 ROLL - B->R 81.92 / IP 100 / »  @ Affiche le temps en s
Je suis curieux d'apprendre combien de secondes met une HP-48 pour déterminer le vol de 77031 avec ces deux versions.
par C.Ret
14 oct. 2014 21:37
Forum : Tous les Pockets
Sujet : Misez p'tit, optimisez n°59 : l'équation de l'œuf.
Réponses : 75
Vues : 39900

Re: Misez p'tit, optimisez n°59 : l'équation de l'œuf.

Bonsoir chers confrères,

La forme des œufs, et notamment ceux des poules, est un sujet très important en agro-alimentaire.
Et donc leur surface, leur forme et leur volume ont fait et font encore l'objet d’études très importantes pour l'I.N.R.A. à cause des retombées économiques et pour l'optimisation de la production des 13 milliards d'œufs produit annuellement dans le pays ; de quoi faire une omelette de plus de 761000 tonnes (cf. bilan 2012 de l'Institut Technique de l'AVIculture).

Image

Afin de répondre au mieux à ce très intéressant M.P.O., je prendrai, étant donné l'importance gastronomique du sujet, des références sérieuses et je ne me fierai qu’aux publications de l'I.N.R.A., illustre institut, et notamment aux travaux menés à la Station de Recherche Avicoles, Centre National de Recherches Zootechniques de Jouy-en-Josas (Seine et Oise) en particulier les publications des Professeurs Y. BONNET et P. MONGIN qui concernent la Mesure de la Surface et du Volume de l'Œuf. (Ann. Zootech. 1965 14 (4) p. 311-317 )

Ces éminents spécialistes ont constaté que le rapport entre la longueur L de l'œuf et son grand diamètre D varient considérablement selon l'espèce de la poule pondeuse, son âge et son alimentation.

Il n'est donc pas possible d'envisager un calcul sérieux du volume de l'œuf de poule et donc du volume d'un œuf sans préciser conjointement son grand diamètre (mesuré avec soin et perpendiculairement à l'axe de l'œuf à l'aide d'un pied à coulisse) et de sa longueur (mesuré avec soin dans l'axe de l'œuf avec le même instrument en veillant bien à le faire exactement dans l’axe).

Toujours d'après ces mêmes travaux de recherche, et en se limitant à l'étude des œufs pondus le même jour par 45 poules croisées Rhodes-Island × Wyandotte de la souche M 41, d'observer une dispersion du rapport L/D :
*** entre 1.238 et 1.491 avec une moyenne de L/D = 1.357 et un écart-type de 0.081 observés sur les œufs pesant entre 55 et 60 g
*** entre 1.288 et 1.416 avec une moyenne de L/D = 1.361 et un écart-type de 0.042 observés sur les œufs pesant entre 60 et 70 g

Il en résulte que le calcul du volume d’un œuf de poule croisée Rhodes-Island × Wyandotte souche M 41 ne peut s’établir qu’à partir de la donnée des trois variables suivantes :
- Son poids P (exprimé en gramme) et qui varie en fonction de la fraicheur de l’œuf,
- Sa longueur L (en cm) ou hauteur si comme Christophe Colomb on le place debout)0 mesuré le long de son axe de symétrie et
- Son plus grand diamètre D (en cm) mesuré perpendiculairement à l’axe de symétrie

Image

Pour obtenir le volume V et la surface d’un œuf de poule, se munir de :
- le(s) œuf(s) à mesurer,
- un pied à coulisse
- une balance de ménage
- un SHARP PC-1211 (éventuellement muni d’une interface CE-21 ou CE-22)

PROCEDURE :

-1-Mettre en fonctionnement le SHARP PC-1211 et saisir le code suivant :

Code : Tout sélectionner

 
10:INPUT "POIDS    (G ) ";P : IF (P<55)+(P>75) END
20:INPUT "LONGUEUR (MM) ";L : IF (L<60)+(L>90) END
30:INPUT "DIAMETRE (MM) ";D : IF (D<40)+(D>80)+(D>=L) END
40:IF P<=60 LET K=4.67 : IF (L<1.114D)+ (L>1.6D) END
50:IF P>60  LET K=4.68 : IF (L<1.235D)+ (L>1.487D) END
60:IF P>70  LET K=4.69
60:LET V=ΠLDD/6.089 , S=KP^(2/3) : USING "########.#"
70:PRINT V;"=V";S;"=S" : END
-2- Vérifier que le code ci-dessus en convenablement chargé dans le SHARP PC-1211 et que celui-ci fait bien 169,6 g une fois posé sur la balance.

-3- Retirer le pocket de la balance et lancer le programme en tapant RUN suivi d’une pression sur la touche [ENTER]

-4- Peser l’oeuf puis utiliser le câble de l’interface CE-22 afin de mesurer convenablement la longueur puis le grand diamètre de l’œuf à l'aide du pied à coulisse.

-5- Saisir les données au fur et à mesure des opérations à l’aide du clavier numérique du SHARP PC-1211 et valider chaque saisie par la touche [ENTER]

-6- S’il s’agit bien d’un œuf de poule, le programme affichera volume et surface de l’œuf respectivement en mm³ et mm².

-7- Si le SHARP PC-1211 affiche le symbole ‘>’ à l’écran, il ne s’agit pas d’un œuf de poule dont le programme peut déterminer le volume ou la surface. Dans ce cas, se munir d’un œuf de poule conforme et relancer l’opération au point -3-

-8- Veiller à ce que l'huile noire de l'affichage ne contamine pas l'oeuf ce qui le rendrait immédiatement impropre à la consommation.
par C.Ret
13 oct. 2014 21:16
Forum : Tous les Pockets
Sujet : Misez p'tit, optimisez n°59 : l'équation de l'œuf.
Réponses : 75
Vues : 39900

Re: Misez p'tit, optimisez n°59 : l'équation de l'œuf.

Bonsoir,

Chouette un M.P.O.

Si je comprends bien, il fut écrire un programme qui calcule le volume d'un oeuf de diamètre d = 60 mm !
Mais qu'elle est sa hauteur ? Ne faut-il pas ces deux paramètre pour décrire complètement un oeuf de poule ?
Et est-ce bien un oeuf de poule ?

Par ailleurs, s'il s'agit d'un M.P.O., il faut écrire un programme et non simplement effectuer un calcul. A moins qu'il ne s'agisse d'un programme non paramètrique qui effectue simplement un calcul compliqué.

En tout cas, je m'y colle. Ou tout au moins je cherche, dans un premier temps, à réaliser un programme qui calcule le volume V d'un oeuf de poule de diamètre d et de hauteur h.
Image
Dans un second temps,je chercherai à l'optimiser...
par C.Ret
12 oct. 2014 17:36
Forum : Tous les Pockets
Sujet : Symbole Casio FX-880P
Réponses : 38
Vues : 20671

Re: Symbole Casio FX-880P

Je ne conais pas cette machine.

Mais sur d'autre pour insérer des caractères spéciaux dans les programmes, on utilise parfois un mode de programmation de certaines touches (mode RESERVE)
Sur d'autre, on utilise l'affichage afin d'inserer un numéro de ligne et obtenir ces codes dans le programme (cf. pocket BASIC)

Pour d'autre, les caractères sont obtenu par une combinaison de touche (shift ou autre) qui permet de saisir ces caractère directement, même s'ils ne sont pas dessiné sur le clavier (cas des caractères spéciaux sur TI-74).

Sinon, il faut peut-être importer le programme depuis une autre calculette ou un environnement de programmation... ??
par C.Ret
28 sept. 2014 21:06
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

Salut Gilles59
... heureux de te retrouver sur le forum.


Le test ABS(M)<>INT(M) est en fait la contraction de deux tests :
- le premier qui veut que M soit positif
- le second que M soit un entier.

En fait, l'idée est de ne traiter que les cas où la différence est multiple de 6 (car il n'y a pas de solution pour le dernier chiffre autre que 0, 0, 6, 24, 60, 120, 210, 336, 504 et 720 . Toutes ces valeurs sont effectivement des multiples de 6 ).
Et il faut que la différence soit positive, si elle est négative, on est déjà trop loin et l'on passera alors à la dizaine suivante.

Mais il s'agit d'une version obsolette pour PC-1211 (cf. post du 04 Sep 2014 ci-dessus) qui ne donne pas tous les résultats.
En effet, l'estimation de D est mauvaise, le code suivant est plus efficace :

Code : Tout sélectionner

1:N=0: FOR A=0 TO 9: C=AAA: FOR B=0 TO 9: M=(N-C-BBB)/6: IF ABS M<>INT M GOTO 3
2:D=INT (2M^.32: IF 6M+D=DDD PRINT N+D:IF D=0 PRINT N+1
3:N=N+10: NEXT B:NEXT A: BEEP 1: END
Il suit le même principe de fonctionnement. On parcours les deux premiers chiffres (centaines et dizaines) et l'unité est estimée, mais uniquement dans les cas favorable pour gagner du temps.

A B et D sont les trois chiffres du nombre N
Comme on parcours tous les chiffres A et B, la valeur de N est incrémenté de 10 à chaque tour à la ligne 3:
La ligne 2: estime la valeur du dernier chiffre D à l'aide de la formule magique qui n'est valable que pour les M entiers positifs ou nuls.
Il faut cependant malgré tout vérifier que la valeur D estimée est solution. En effet, il y a pas mal de cas où l'on passe par la ligne 2: sans que le D calculé ne soit une solution. D'où le test 6M+D=DDD

Ce code est rapide (mais j'en ai donné un autre encore plus rapide).

Cependant, ce n'est pas le plus court.
En effet, si l'on ne tient pas compte de la rapidité, le code le plus concit serait du style :

Code : Tout sélectionner

1: FOR N=0 TO 999 : S=N , X=N
2: IF X LET D=X , X=INT .1X , D=D-10X , S=S-DDD : GOTO 2
3: IF S=0 PRINT N
4: NEXT N : END
70 octets seulement.

Il affiche les solutions 0. 1. 153. 370. 371. et 407. en environ 47 min et s'arrête au bout du double de temps.
par C.Ret
07 sept. 2014 15:54
Forum : Tous les ordinateurs
Sujet : montage d'un systeme S100
Réponses : 67
Vues : 57893

Re: montage d'un systeme S100

Félicitations...

Cela à belle allure et semble fonctionner parfaitement.

Y compris le BASIC qui donne les bonnes réponseS du M.P.O. à la mode ce Week-End.
par C.Ret
07 sept. 2014 15:05
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

Bon, pour les maux de tête, rien de tel qu'une bonne nuit de sommeil...
J'espère que tout le monde a bien dormi, car encore des coderies :

J'obtiens les résultats en un peu moins de 16 secondes sur TI-74 avec le code suivant :

Code : Tout sélectionner

5 DIM D(2,9)
10 FOR I=1 TO 9:C=I*I*I:D(0,I)=(C-I)/6:D(1,I)=(10*I-C)/6
20 D(2,I)=15*I+D(1,I):NEXT I:S$=""
30 M=D(2,A)+D(1,B):IF ABS(M)=INT(M) THEN C=INT(2*M^.32) ELSE 60
40 IF M=D(0,C)THEN PRINT S$;A;B;C;:S$=" & ";:IF C=0 THEN PRINT S$;A;B;1;
50 IF M>0 AND B<8 THEN B=B+2:GOTO 30
60 IF A<9 THEN A=A+1:P=1-P:B=P:GOTO 30
70 PRINT ".":PAUSE :END
Et l'affichage final:

Code : Tout sélectionner

_0  0  0  &  0  0  1  &  1  5  7  &  3  7  0  &  3  7  1  &  4  0  7 .
Qui ressemble très fortement à cette version pour QBASIC:

Code : Tout sélectionner

 5 DIM D(2,9) AS SINGLE
   DEFINT A-C, I, P
   DEFSNG M
   DEFSTR S$

REM ====== Initialisation 
10 FOR I=1 TO 9
   :  C=I*I*I : D(0,I)=(C-I)/6 : D(1,I)=(10*I-C)/6
 : D(2,I)=15*I+D(1,I)
   NEXT I : S$="" : P=0

REM ====== Boucle de Recherche
20 FOR A=0 TO 9
   :  FOR B=P TO 9 STEP 2
30 :  :  M=D(2,A)+D(1,B)
   :  :  IF ABS(M)=INT(M) THEN C=INT(2*M^.32) ELSE EXIT FOR
40 :  :  IF M=D(0,C) THEN PRINT S$;A;B;C; : S$=" & "; : IF C=0 THEN PRINT S$;A;B;1;
50 :  NEXT B : P=1-P
60 NEXT A

REM ====== Finalisation Affichage
   PRINT "." : END
Comme quoi je pense que le code pour TI-74 peut être encore optimiser.



Et la codderie pour machine RPL :
Là peut-être qu'il ne va falloir analyse cela que cet après-midi après une bonne sieste :
J'ai imaginé le code suivant et je donne à droite les raisons de ne pas l'utiliser pour un MPO

Code : Tout sélectionner

« { }                                            //       Initialise la liste qui contiendra les résultats
  0 9 FOR a                                      // x10   Boucles sur a                                       
      0 9 FOR b                                  // x100  Boucles sur b 
          0 9 FOR c                              // x1000 Boucles sur c
              100 a * 10 b * c + +               //       Calcul de n=abc      2000x multiplications et additions
              a a a * * b b b * * c c c * * + +  //       Calcul de s=a3+b3+c3 6000x multiplications et 2000 additions de plus
              IF OVER == THEN + ELSE DROP END    //       Plus de 1000 tests pour au total ajouter au plus 6 entiers à la liste
          NEXT                                   //      Boucle sur  c (mais une seule solution existe à chaque b sauf pour c=0)
      NEXT                                       //    Boucle sur b pair et impair independemment de parité de a
   NEXT                                          //  Boucle sur a
»                                                //  Retune la liste résultat { 0 1 153 370 371 407 } après environ 2 min.
2 min c'est pas mal pour exécuter presque 40000 instructions dont 8000 multiplications et 4000 additions.
Cela fait une moyenne de ~330 commandes par seconde.

On peut diviser par deux le temps d'exécution en évitant de répéter systématiquemetn les calculs :
Comme le RPL permet de manipuler des couples (a,b), les fonctions de gestion des complexes R->C et C->R sont utilisées pour limiter les manipulations de la pile. Ce qui permet de n'utiliser qu'un seul niveau de pile pour mémoriser les valeurs des somme aprtielles n et s.

Code : Tout sélectionner

« { }                                            //       Initialise la liste qui contiendra les résultats
  0 9 FOR a                                      // x10   Boucles sur a                                       
      100 a * a a a * * R->C                     //       Calcul de na et sa que l'on laisse dans la pile sous form de couple (na,sa)
      0 9 FOR b                                  // x100  Boucles sur b 
          10 b * b b b * * R->C                  //       Calcul de nb et sb
          OVER +                                 //       Calcul de na+nb et sa+sb que l'on laisse dans la pile (na+nb,sa+sb)
          0 9 FOR c                              // x1000 Boucles sur c
              c c c c * * R->C                   //       Calcul de nc et N-S
              OVER +                             //       Calcul de N S qui fait 2330x multiplications et 1100 additions 2110 réarrangements R->C/C->R
              C->R                               //       On remet N et S dans la pile 
              IF OVER ==                         //       Les mêmes 1000 tests pour ajouter les 6 entiers solution à la liste
              THEN 4 ROLL + ROT ROT              //       Ajoute n à la liste des résultats totu en préservant (na,sa) et (na+nb,sa+sb)
              ELSE DROP END                      
          NEXT                                   //      Boucle sur  c (mais une seule solution existe à chaque b sauf pour c=0)
          DROP                                   //      Efface (na+nb,sa+sb) devenu obsolète
      NEXT                                       //    Boucle sur b pair et impair independemment de parité de a
      DROP                                       //    Efface (na,sa) devenu obsolette
   NEXT                                          //  Boucle sur a
»                                                //  Retune la liste résultat { 407 371 370 153 1 0 } après 1 min 10s
On peut encore économiser du temps en ne parcourrant pas toute les valeurs de b mais uniquement celles correspondant à la parité de a.

Code : Tout sélectionner

« DEG { }                                          //       Initialise la liste qui contiendra les résultats
  0 9 FOR a                                        // x10  Boucles sur a                                       
      100 a * a a a * * R->C                       //       Calcul de na et sa que l'on laisse dans la pile sous form de couple (na,sa)
      a 2 MOD 9 FOR b                              // x50  Boucles sur b 
          10 b * b b b * * R->C                    //       Calcul de nb et sb
          OVER +                                   //       Calcul de na+nb et sa+sb que l'on laisse dans la pile (na+nb,sa+sb)
          0 9 FOR c                                // x500 Boucles sur c
              c c c c * * R->C                     //       Calcul de nc et N-S
              OVER +                               //       Calcul de N S qui fait 680x multiplications et 550 additions 1050 réarrangements R->C/C->R
              IF ARG 45 ==                         //       Test modifié qui évite un réarrangement tests 
              THEN ROT a b c ->ARRY + ROT ROT END  // x6   Ajoute [abc] à la liste des résultats 
          NEXT                                     //      Boucle sur  c (mais une seule solution existe à chaque b sauf pour c=0)
          DROP                                     //      Efface (na+nb,sa+sb) devenu obsolète
      2 STEP                                       //    Boucle sur b pair et impair independemment de parité de a
      DROP                                         //    Efface (na,sa) devenu obsolette
   NEXT                                            //  Boucle sur a
»                                                  //  Returne la liste résultat après environ 49s
Reste que la partie qui fait le plus économiser et de supprimer la boucle intérieure en estimant pour chaque couple (a,b)une valeur de c que l'on teste:

Code : Tout sélectionner

« { }                                              //       Initialise la liste qui contiendra les résultats
  0 9 FOR a                                        // x10  Boucles sur a                                       
    100 a * a 3 ^ R->C                             //       Calcul de da=na-sa que l'on laisse dans la pile
    a 2 MOD 9 FOR b                                // x50  Boucles sur b 
      10 b * b 3 ^ R->C                            //       Calcul de db=nb-sb que l'on laisse dans la pile
      OVER + C->R OVER - NEG 6 /                   //       Calcul du sixième de la difèrence M=(da+db)/6= (na+nb-sa-db)/6
      IF DUP ABS OVER IP == THEN                   //      Test combiné de signe et de mltiplicité
        DUP .32 ^ 2 * FLOOR -> n m c               //  x500    Calcul estimation de c = FLOOR(2.M^.32)
        « IF m 6 * c + c 3 ^ == THEN               //        Test que c estimé est effectivement une solution
            SWAP n c + +                           //          Ajoute la solution n+c à la liste
            IF c NOT THEN n 1 + + END              //          Ainsi que la solution n+1 lorsque c==0                  
            SWAP 999                               //          Sort de la boucle FOR b - une seule solution possible pour chaque couple a,b
          ELSE 2 END »                             //        Si c n'est pas solution, cherche le b suivant
      ELSE DROP2 999 END                           //        A défaut de commande ABORT ou EXIT FOR un 999 STEP fera l'affaire ici 
    STEP  DROP                                     //    Boucle sur b pair et impair independemment de parité de a // Efface da=na-sa devenu obsolette 
  NEXT                                             //  Boucle sur a
»                                                  //  Returne la liste résultat { 0 1 153 370 371 407 } après 10s
Le gain de temps est appréciable, les calculs compliqués ne se faisant que de temps en temps, c'est à dire lorsque la somme partielle est multiple de 6.
Les valeurs b parcourrues sont celle correspondant à la parité de a et de plus, on sort de la boucle dès que les sommes partielle sont négatives. Les cubes croissants plus rapidement que les valeurs linéaires issues de b,


On peut diminuer ce temps avec un code à peine plus compliqué : La fonction DOT est utilisée pour calculer la valeur de l'entier à partir du triplet [a b c]. Ce qui évite d'avoir à manipuler les sommes parcielles et donc instruction des nombres complexes.

Code : Tout sélectionner

« { }                                              //       Initialise la liste qui contiendra les résultats
  0 9 FOR a                                        // x10  Boucles sur a                                       
    'Dat58' 21 a + GET                             //       Calcul de da=na-sa à partir de ma matrice pré-calculée 
    a 2 MOD 9 FOR b                                // x50  Boucles sur b 
      'Dat58' 11 b + GET                           //       Calcul de db=nb-sb à partir de la matrice Dat58
      OVER +                                       //       Calcul du sixième de la difèrence M=(da+db)/6
      IF DUP ABS OVER IP == THEN                   //      Test combiné de signe et de mltiplicité
        DUP .32 ^ 2 * FLOOR -> c                   //         Calcul estimation de c = FLOOR(2.M^.32)
        « IF 6 * 'Dat58' 1 c + GET == THEN         //         Test que c estimé est effectivement une solution
            SWAP a b c 3 ->ARRY [100 10 1] DOT     // x6         Ajoute la solution n+c à la liste
            IF c NOT THEN DUP 1 + {} + + END       //            Ainsi que la solution n+1 lorsque c==0                  
            + SWAP 999                             //           Sort de la boucle FOR b (il n'y a qu'une solution
          ELSE 2 END »                             //         Si c n'est pas solution, cherche le b suivant
      ELSE DROP 999 END                           //        A défaut de commande ABORT ou EXIT FOR un 999 STEP fera l'affaire ici sortir  
    STEP  DROP                                     //    Boucle sur b pair et impair independemment de parité de a 
                                                          // Efface da=na-sa devenu obsolette 
  NEXT                                             //  Boucle sur a
»                                                  //  Returne la liste résultat { 0 1 153 370 371 407 } après 8s


DAT58:                                             // Matrice prè-calculée contenant les sixièmes des diffèrences partielles
[[  0     0     1     4    10    20    35    56    84   120  ]
 [  0     1.5   2      .5  -4   -12.5 -26   -45.5 -72  -106.5]
 [  0    16.5  32    45.5  56    62.5  64    59.5  48   +28.5]]
Le gain de temps provient que cette fois on ne réalise qu'une centaine d'addition et deux centaines de multiplications, autant de calcul de puissance , en comptant celles nécessaire à la création des 3à éléments de la matrice 'Dat58'

Ce qui fait, que malgré la gestion plus sophistiqué de la pile, on gangne du temps surtout que en évitant la répétition des calculs identique lors de la répétition des boucles FOR b
par C.Ret
06 sept. 2014 18:00
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

Ah!Oui pardon, important le programme utilise 221 octets (reste 1203 Step sur les 1424 Steps disponibles iniitalement) et aucune des variables au-delà de Z.

EDIT:
Il en existe maintenant (31/10/2017) une version plus légère:

Code : Tout sélectionner

1: CLEAR : F=1.5, G=2, H=.5, I=-4, J=-12.5, K=-26, L=-45.5, M=-72, N=-106.5                       (61)
2: D=Z+A(5+B): IF ABS D=INT D LET C=INT 2D^.32: IF D=1.5C-A(5+C) PRINT A;B;C: IF C=0 PRINT A;B;1  (62)
3: IF D>0 IF B<9-Y LET B=B+2: GOTO 2                                                              (22)
4: IF A<9 LET A=A+1, Z=15A+A(5+A), Y=1-Y, B=Y: GOTO 2                                             (39)
                                                                                                  184 octets
L'astuce est que seul le tableau des B(i) est mémorisé. Les valeurs A(i) et C(i) sont calculées à la demande respectivement avec la formule de la version originale en ligne 4 " Z=15a+B(a) " pour A(a) et lors du test en ligne 2 " D=1.5c-B(c) " pour C(c).
par C.Ret
06 sept. 2014 12:36
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

Je sais pas mais j'arrive à imprimer les résultats avec mon SHARP PC-1211 sur son CE-122 en moins de 1'18" (avec A allant jusque 9) et sans calculer aucun cube (en fait ils sont près-calculés !

Code : Tout sélectionner

1: CLEAR : F=1.5, G=2, H=.5, I=-4, J=-12.5, K=-26, L=-45.5, M=-72, N=-106.5
2: Q=1, R=4, S=10, T=20, U=35, V=56, W=84, X=120  
3: D=Z+A(5+B): IF ABS D=INT D LET C=INT 2D^.32: IF D=A(15+C) PRINT A;B;C: IF C=0 PRINT A;B;Q
4: IF D>0 IF B<9-Y LET B=B+2: GOTO 3
5: IF A<9 LET A=A+1, Z=15A+A(5+A), Y=1-Y, B=Y: GOTO 3
EDIT:
221 octets de programme - utilise pleinement les registres A à Z inclu.


Résultats et temps d'impression :

Code : Tout sélectionner

0.0.0.   4"   0.0.1.   5"   1.5.3.  11"   3.7.1.  29"   4.0.7.  31"   Fin   1'18"
Petit rappel, sur le PC-1211, les variables alphabétiques correspondent au tableau unique A() avec les correspondance A=A(1), B=A(2), C=A(3), ... Z=A(26),

Ainsi les variables A(5) à A(14) - respectivement E à N - correspondent aux sixièmes pré-calculés de 10B-B^3 dont les valeurs non nulles sont programmées à la ligne 1:
Et les variables A(15) à A(24) - respectivement de O à X - correspondent aux sixièmes pré-calculés de C-C^3

Code : Tout sélectionner

A:	centaines de N	  a		N:B(9)	(90-729)/6	-106.5		(  0-  0)/6=  0. =  0+  0.
B:	dixaines de N	  b		O:C(0)	(  0- 0)/6	   0.		(100-  1)/6= 16.5= 15+  1.5
C:	unités de N	  c		P:C(1)	(  1- 1)/6	   0.		(200-  8)/6= 32. = 30+  2.
D:	sixièmes de N-a^3-b^3		Q:C(2)	(  8- 2)/6	   1.		(300- 27)/6= 45.5= 45+   .5
E:B(0)	( 0-  0)/6	  0.		R:C(3)	( 27- 3)/6	   4.		(400- 64)/6= 56. = 60-  4.
F:B(1)	(10-  1)/6	  1.5		S:C(4)	( 64- 4)/6	  10.		(500-125)/6= 62.5= 75- 12.5
G:B(2)	(20-  8)/6	  2.		T:C(5)	(125- 5)/6	  20.		(600-216)/6= 64. = 90- 26.
H:B(3)	(30- 27)/6	   .5		U:C(6)	(216- 6)/6	  35.		(700-343)/6= 59.5=105- 45.5
I:B(4)	(40- 64)/6	- 4.		V:C(7)	(343- 7)/6	  56.		(800-512)/6= 48. =120- 72.
J:B(5)	(50-125)/6	-12.5		W:C(8)	(512- 8)/6	  84.		(900-729)/6= 28.5=135-106.5
K:B(6)	(60-216)/6	-26.		X:C(9)	(729- 9)/6	 120.
L:B(7)	(70-343)/6	-45.5		Y:  a & b pair <=0=:=1=> a & b impair
M:B(8)	(80-512)/6	-72		Z:A(a)	15*a+B(a)
Les sixièmes correspondant aux centaines ne sont pas près-calculés, ils se déduisent simplement de la valeur du sixième liée à la dizaine correspondante. En effet, on constate qu'il suffi d'ajouter 15*a au sixième de la dizaine a. (cf. Z=15*a+B(a) à la ligne 5: ) La valeur Z contient donc la valeur du sixième des centaines pour éviter de la calculer à chaque nouvelle dizaine testée.

Les variables A,B et C sont respectivement les trois chiffres de n = abc

La variable D est le sixième de la différence entre l'entier n et la somme s=a^3 + b^3 + c^3 des cubes de ses chiffres.

Petite astuce supplémentaire, pour les entiers solution, on remarque que les chiffres a et b sont toujours de même parité. Ce qui se justifie, on veut obtenir un multiple, donc une valeur entière. Or les sixièmes sont tous des entiers ou des demi-entiers. Ainsi la variable Y est utilisée pour ne tester que les chiffres B de même parité que le chiffre A.

Un gain de temps important est obtenu par rapport à la version précédente car pour chaque A, on ne parcourt que la moitié des valeurs de B (cf. B<-B+2 de la ligne 4 ).
Explication des lignes:
1: Initialisation des sixièmes pré-calculé pour les dizaines (et indirectement pour les centaines)
2: Initialisation des sixième près-calculé pour les unités
3: Boucle principale : calcul de la différence D, estimation du dernier chiffre, test et affichage de(s) entier(s)
4: Valeur suivante de B: en fonction de la parité (donnée par Y) ou passe au chiffre B suivant
5: Valeur suivante de A: incrément de A, calcul de Z, changement de parité et fin de boucle

P.S.: Même code mais pour une machine gérant les tableaux

Code : Tout sélectionner

10: CLR: DIM B(9),C%(9)
11: B(1)=1.5: B(2)=2: B(3)=.5: B(4)=-4: B(5)=-12.5: B(6)=-26: B(7)=-45.5: B(8)=-72: B(9)=-106.5
12: C%(2)=1: C%(3)=4: C%(4)=10: C%(5)=20: C%(6)=35: C%(7)=56: C%(8)=84: C%(9)=120  
13: D=Z+B(B%): IF ABS(D)=INT(D) THEN C%=2*D^.32: IF D=C%(C%) PRINT A%;B%;C%:IF C%=0 PRINT A%;B%;1
14: IF D>0 AND B%<9-Y% THEN B%=B%+2: GOTO 13
15: IF A%<9 THEN A%=A%+1: Z=15*A%+B(A%): Y%=1-Y%: B%=Y%: GOTO 13
par C.Ret
05 sept. 2014 19:06
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

gege a écrit :Bonjour,
[...]On doit encore pouvoir gratter 5 secondes ?
G.E.
Oh! Oui facilement, car la version actuelle parcourt tous les A (de 0 à 9) et tous les B (de 0 à 9)
De la même façon que la boucle interne cherchant C a été éliminé, il doit être possible d'économiser de précieuses secondes en ne parcourant pas tous les B à chaque A ! :idea:

Sans compter que l'on peut faire sans calculer le cube d'aucune valeur :twisted: :twisted:
par C.Ret
04 sept. 2014 17:42
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

gege a écrit : Chouette mais tu 'triches' avec la limite à 5 sur A !
[...]
Quel est le temps sur PC1211 ?
[...]
A tous, est-ce que je peux incorporer vos trucs dans mon article (en citant les pseudos) ?
Pas de souci pour incorporer, utiliser, copier ou transformer tout ce que je met sur le forum. C'est publier pour être publique et servir à chacun.
Effectivement, je vais réflèchir à une version où A va jusqu'à 9 afin de comparer les "vitesses". Mais concernant ce point c'est plutôt les "lenteurs". Je suis comme Marge, avec mon matériel, je concours pour le programme le plus lent.

Le code ci-dessus n'a pu être testé qu'à l'instant de retour de mission, j'ai enfin pu mettre la main sur mon PC-1211 et sa CE-122).
Le programme s'arrête après environ 2 min mais il manque des valeurs. Je crois que Zalm a trouvé l'origine du problème. L'approximation de D établie sur un Commodore C128D ne semble pas fonctionner sur une vraie calculatrice.
zpalm a écrit : Ce programme est plein d'astuces !! Mais es-tu sûr de ta formule en ligne 20 ?

Code : Tout sélectionner

20:D=INT (.516685+√M)
Je n'ai pas l'impression qu'elle donne tous les bons résultats... contrairement à celle de gege [... formule trop compliquée...]
Et pour pinailler un peu, sur la ligne 10 on pourrait sortir AAA de la boucle FOR B.
Effectivement, je dois corriger cela.
EDIT
Le code ci-dessous devrait mieux fonctionner

Code : Tout sélectionner

1:N=0: FOR A=0 TO 9: C=AAA: FOR B=0 TO 9: M=(N-C-BBB)/6: IF ABS M<>INT M GOTO 3
2:D=INT (2M^.32: IF 6M+D=DDD PRINT N+D:IF D=0 PRINT N+1
3:N=N+10: NEXT B:NEXT A: BEEP 1: END
Les résultats 0. (3s) 1. (4s) 153 (24s) 370.(52s) 371.(54s) 407. (60s) crépitent sur l'imprimante très rapidement (lentement ?)
Le BEEP retentit après 2min17s en testant jusqu'à A=9.

On notera que ma formule d'estimation de D n'a rien avoir, mais alors rien du tout avec les formules très compliquées de notre ami gégé.
Mais absolument rien avoir du tout du tout.[/color]

Concernant les AAA BBB et DDD j'ai même une forte envie de tous les sortir du programme.


EDIT:
L'idée est que comme on parcourt toutes les valeurs de A et B, on peut , à chaque boucle déduire la valer de N avec N <- N+10
L'idée est que C-BBB évolue aussi de la même façon entre deux valeurs successive de B . Idem pour A dont les N-AAA évoluent de façon régulière à chaque pas.


... à suivre
par C.Ret
03 sept. 2014 23:49
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

gege a écrit :Uh ?
A part :
10 PRINT "0 1 153 370 371 407"
je ne vois rien sous la seconde sur PC1211...
Quel est le truc ?
G.E.
C'est bien cela
1:PRINT "0 1 153 370 371 407":END

Non mais c'est de la gruge !

Sinon, ton dernier programme peut être MPO-iser
Toutes les valeurs de A et B sont parcourues, donc les 100*A et 10*B sont inutiles, il suffit d'un N=N+10 bien placé.
Ensuite les lignes 30 et 40 reviennent à faire un IF (0<E) OR (E<720). Ce qui m'a donné l'idée de simplifier mon code ; au lieu de tester 0<M et M<>INT(M), je teste ABS M<>INT M

Et l'dée du test C=1 pour afficher N+1 est excellente:

D'où ma version de ce programme pour SHARP PC-1211 qui recherche les entiers de trois chiffres :

Code : Tout sélectionner

10:FOR A=0 TO 5:FOR B=0 TO 9:M=(N-AAA-BBB)/6:IF ABS M<>INT M GOTO 30
20:D=INT (.516685+√M):IF 6M+D=DDD PRINT N+D:IF D=0 PRINT N+1
30:N=N+10:NEXT B:NEXT A:END

[/code]
par C.Ret
01 sept. 2014 23:24
Forum : Tous les Pockets
Sujet : Misez p'tit Optimisez n°58 : somme des cubes des chiffres
Réponses : 66
Vues : 50810

Re: Misez p'tit Optimisez n°58 : somme des cubes des chiffre

dprtl a écrit :
zpalm a écrit :Sur HP Prime, moins de 3 dixièmes de seconde pour parcourir les nombres de 0 à 1000
Tellement rapide, que ça ne vaut même plus le coup de chercher à optimiser :)

N'empêche que j'ai aussi rapide qu'une HP Prime sur mon SHARP PC-1211 !
Sauf si j'allume l'imprimante, il me faut alors 3 secondes de plus qu'une HP Prime :D

Aller à la recherche avancée