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

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

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°58 : somme des cubes des chiffre

Message par C.Ret »

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).
Modifié en dernier par C.Ret le 31 oct. 2017 11:07, modifié 5 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
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°58 : somme des cubes des chiffre

Message par gege »

Boudiou j'ai mal à la tête en regardant ce code !
A décoder...
Bravo
G.E..
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°58 : somme des cubes des chiffre

Message par C.Ret »

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
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.
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

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

Message par Gilles59 »

Bonjour à tous! je reviens après une longue absence ;D

Solution RPL en 81,5 octets bourin utilisant l'indispensable library http://www.musikwissenschaft.uni-mainz. ... GoferLists

Code : Tout sélectionner

{}
1 3000 FOR n 
  n  ->STR Chars STR-> 3 ^ Sum n ==  { n + } IFT 
NEXT

Ce programme retourne la liste { 1 153 370 371 407 }

Quelques explications en supposant n=153 et ce qui se passe sur la pile

{}
1 3000 FOR n      ! No comment
  n               ! {1} 153  // 1 a déjà été trouvé
  ->STR           ! {1} "153"
  Chars           ! {1} {"1" "5" "3"}
  STR->           ! {1} {1 5 3}
  3 ^             ! {1} {1 125 27}
  Sum             ! {1} 153
  n               ! {1} 153 153
  ==              ! {1} 1.
  { n + }         ! {1} 1. { n + }   
  IFT             ! {1 153 }
NEXT
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
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°58 : somme des cubes des chiffre

Message par Marge »

Schön!
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é.
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

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

Message par Gilles59 »

2 versions pour CASIO 602/603P qui recherchent de 0 à 999

Un courte (qui doit être adaptable sur TI57)

Code : Tout sélectionner

PROG1 : 44 pas

999 MinF
LBL1
 MRF / 1 EXP 3 = Min01
 3 Min00 0 Min1F
 LBL2
  MR01 x 10 - INT Min02 = Min01
  MR02 x x = = M+1F
 DSZ GOTO2
 MR1F X=F "#"
 1 M-F
MRF x>=0 GOTO1

Recherche de 0 à 999

602P : 12'05"
603P : 4'30"
Une version 'rapide' :

Code : Tout sélectionner

PROG2 : 76 pas

9 Min01
LBL1
 MR01 x 100 = Min04
 MR01 x x = = Min07
 9 Min02
 LBL2
  MR02 x 10 = Min05
  MR02 x x = = Min08
  9 Min03
  LBL3
   MR04 + MR05 + MR03 - MR07 - MR08 - MR03 x MR03 x MR03 =
   x=0 "AR01 AR02 AR03"
   1 M-03  MR03 x>=0 GOTO3
  1 M-02  MR02 x>=0 GOTO2
 1 M-01 MR01 x>=0 >GOTO1

Recherche de 0 à 999
602P : 4'01"
603P : 1'40"
Pas d'astuces particulières sauf l'utilisation du mode 'constante' pour calculer le cube... Facilement adaptable sur 501 et 502P en supprimant le coté "alpha" ... (grrr je retrouve plus ma 502P, çà m'agace !)
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
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

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

Message par Gilles59 »

C.Ret a écrit : 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
Je ne comprends strictement rien à cette version ;)
Je l'aurai bien adapté sur 602/3 même sans comprendre mais que signifie "IF ABS M<>INT M THEN ..." ?
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
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°58 : somme des cubes des chiffre

Message par C.Ret »

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.
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.
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

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

Message par Gilles59 »

Merci C.Ret pour les explications détaillées ;D

Avec l'algo de Gégé :

Code : Tout sélectionner

Casio 602 / 603P : 86 pas / 16 secondes sur CASIO FX-603P pour une recherche de 0 à 999

9 Min00 Min11
LBL0 MR00 x x = = IND MIN00 DSZ GOTO0

LBL1
 9 Min12
 100 x MR11 - IND MR11  = Min14
 LBL2
   MR14 + 10 x MR12 - IND MR12 = Min15
   x>=0 GOTO3 GOTO4
   LBL3
   - 719 = x>=0 GOTO4
   MR15 x^1/y 3 = RND1 Min13
   + MR15 - IND MR13 = 
   x=0 "AR11 AR12 AR13" 
   x=0 MR13 x=0 "AR11 AR12 1"
  LBL4 
  1 M-12  MR12 x>=0 GOTO2
 1 M-11 MR11 x>=0 GOTO1
A noter
- l'utilisation d'une table pour calculer les cubes, qui fait gagner 3 secondes.
- L'utilisation de la fonction 'racine n-iéme' (x^1/y) pour trouver le cube le plus proche
-L'utilisation de la fonction RND1 (plutot que INT(x+0.5)
- Ca fonctionne,mais j'ai un doute sur l'algorithme,et nous sommes peut-etre un peu chanceux ici.De ce que je comprends on essaie de résoudre à un moment dans |N :
x^3-x=d
qu'on simplifie en x^3~=d => x~=d^(1/3) considérant que x^3 >> x
(d'où d'ailleurs la double solution pour d=0 car 0^3-0=0 et 1^3-1=0 également).
- j'ai essayer d'accélérer avec le test de divisibilité par 6 par on ne gagne quasi rien.

Ca devrait tourner ~ 40" sur 602P (pas loin du PB700 :O )
Comme toujours sur 501/602/603 l'absence de certains tests fait perdre en 'élégance'... Mais les temps sont tres bon pour des machines de ces époques.
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
Avatar du membre
ledudu
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5645
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

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

Message par ledudu »

Machine : Casio PB-2000c
Langage : prolog

scube(X) : appel initial avec X, premier entier testé
cube(X,Y,S): calcul récursif de la somme, quand Y=0, S contient la somme des cubes.
cube(X,0,X) : si Y=0 et S=X l'entier est la somme des cubes de ses chiffres.

Code : Tout sélectionner

scube(X):-cube(X,X,0),fail. 
scube(X):-Y Is X+1,scube(Y). 
cube(X,0,X):-write(X),beep(1),nl. 
cube(X,Y,S):- >(Y,0),Z is integer(Y/10),T is S+(Y-10*Z)^3,cube(X,Z,T). 

?-scube(0).
0
1
153 en 1'05
370 en 3'01
371 en 3'02
407 en 3'27
Modifié en dernier par ledudu le 03 janv. 2016 22:25, modifié 1 fois.
Avatar du membre
ledudu
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5645
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

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

Message par ledudu »

Machine : Casio Pro fx-1
Langage : Fortran Casio

Algo : pour chaque entier,grâce à la fonction log et au sous-prog partie entière je divise par 10^(nombre de chiffres-1) pour me ramener à la forme x,yyyyy
Avec l'algo partie entière, j'extrais x pour le calcul de la somme des cubes et je recommence jusqu'à ce que x=0.

Code : Tout sélectionner

Variables :
0 : entier à traiter
1 : entrée de l'algorithme de partie entière et forme x,yyyyy  
2 : retour de l'algorithme de partie entière  
5 : contient 10 pour le calcul de partie entière
6 ; somme des cubes
7 : zéro

Code : Tout sélectionner

0=K000:5=K10:7=K0:                            pas 18  / Initialisations globales
ST#1:6=7:0=0+K1:1=0 log:goto 9:1=0/2 10x:     pas 47  / Passage à l'entier suivant et à la forme x,yyyyy
ST#2:GOTO 9:6=2*2*2+6:1=1-2*5:IF 1=7:2:3:2:   pas 82  / Somme des cubes par itération
ST#3:IF 0=6:1:4:1:                            pas 96  / Test final
ST#4:Ans 0:GOTO 1:                            pas 105 / Affichage
SUB#9:2=1+5 10x-5 10x:                        pas 118 / Sous-programme de calcul de partie entière - return automatique en fin de programme
D'autres programmes pour PRO Fx-1.
Modifié en dernier par ledudu le 12 mars 2017 17:27, modifié 1 fois.
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°58 : somme des cubes des chiffre

Message par Marge »

Mazette, c'est ledudu 2.0 ! :D ça te fait combien de MPO réglés en 2 jours ? 3 ? 4 ?
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
ledudu
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5645
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

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

Message par ledudu »

:D :D
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

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

Message par Gilles59 »

Je continue mon exploration du NewRPL sur HP50g.

Cet algorithme très naïf :

Code : Tout sélectionner

<<
0 9 FOR 'a'
 0 9 FOR 'b'
  0 9 FOR 'c'
   IF 'a*100+b*10+c==a^3+b^3+c^3' THEN { a b c } EVAL END
  NEXT
 NEXT
NEXT
>>
trouve les 6 solutions (inclus zéro) en 1,06 seconde. On peut descendre à 0,9" en évitant les calculs inutiles et sans doute moins en jonglant avec la pile... A noter que le NewRPL ne traite pas EVAL sur une liste comme le UserRPL : EVAL sur une liste en NewRPL évalue chaque élément de la liste en le laissant dans une liste. C'est plus logique mais çà rompt la compatibilité.

Le programme équivalent en UserRPL est 270 fois (!!) plus lent (il faut enlever les ' ' après les FOR et changer { a b c } EVAL en a b c 3 ->LIST

Une approche différente qui s'exécute en 1,56"

Code : Tout sélectionner

<<  0 999 FOR 'n'  n  DUP ->STR UTF8-> #80h - 3 ^ ΣLIST  == n IFT NEXT >>
Et puisqu'on est dans le misez p'tit une version en 71,5 octets utilisant la Library GoferList pour UserRPL 50g, mais 200" , mode exact requis

Code : Tout sélectionner

 0 999 1 Seq « DUP ->STR Chars STR-> 3 ^ Sum ==  » Filter 
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
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

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

Message par Gilles59 »

Solution proposée par Claudio lapilli le créateur du newrpl sur hpmuseum


Code : Tout sélectionner

<< 0 999 FOR 'n' 
   n 0 0  DIGITS 3 ^
   n 1 1  DIGITS 3 ^ +
   n 2 2  DIGITS 3 ^ +
   n == n IFT
 NEXT
 >>
0,57 sec

Le newrpl est vraiment très bien. Je regrette cependant le choix de révolutionner totalement l'interface des menus, j'aurai préféré plus de conservatisme de ce point de vue. A noter que Claudio laisse entendre que le new rpl pourrait s'installer sur la prime à l'avenir.
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 »