Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

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 : 3421
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par C.Ret »

zpalm a écrit :

Code : Tout sélectionner

              102 d – 2 / FLOOR +   //          Comptages 2c et 1c 
Je vois que tu as modifié ta formule dans le code :wink:
Oui, le problème est de bien cerner la valeur limite dans les boucles. En particulier c'est plus n = n + 1 + INT((100-d)/2) qui se produit, car il faut ajouter 1 (c'est à dire compter le cas où aucune pièce de 2c ou 1c n'est nécessaire lorsque d=100) !

C'est pour la même raison que le code pour SHARP PC-1211 initialise T à 5, c'est à cause des cas limites où le SHARP PC-1211 "oublie" pour chaque boucle une des itérations. Apparemment un soucis d'arrondi dans le test de fin de boucle FOR/TO/STEP/NEXT.

Gilles59 a écrit :L'algo de dprtl est vraiment très simple et très malin ! Et hyper rapide au passage ...
++
Gilles59 a écrit :je confirme qu'il donne le résultat correct, mais à vrai dire je ne comprends pas _pourquoi_ çà marche :O
Il y a là un subtilité mathématique qui m'echappe
Tu n'es pas le seul, j'éprouve moi aussi pas mal de difficultés à bien formalier tout cela. Mais c'est vrai que je n'ai jamais été bon en dénombrements.
Gilles59 a écrit :Et C.ret en rajoute une couche en supprimant la boucle des 2 centimes ...
C'était par accident, juste à chercher à MPO-iser le code de dprtl
Gilles59 a écrit :Et pourquoi pas la boucles de 5 centimes ?
C'est en court, je suis en train de préparer quelques couches de plus.
Existerait il une formule qui donne directement le nombre de solutions sans boucle aucune ?
Cette formule doit exister, car sinon zpalm n'aurait pas d'aussi bon résultats avec une RPN !
En tout cas, elle doit dépendre des rapports entre les valeurs des pièces. Une forme canonique peut-être ?
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
bernouilli92
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5268
Enregistré le : 21 nov. 2012 13:03
Localisation : Ile de France

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par bernouilli92 »

Gilles59 a écrit :
Dans ces deux dernières versions, Je pense qu'il manque le test if b+c+d +e+f=100:;n:=n+1
...

L'algo de dprtl est vraiment très simple et très malin ! Et hyper rapide au passage ... je confirme qu'il donne le résultat correct, mais à vrai dire je ne comprends pas _pourquoi_ çà marche :O Je l'ai adapté 'bêtement'

Il y a là un subtilité mathématique qui m'echappe
...
Pareil , j'ai encore du mal à comprendre ce que cela fait exactement.

C.Ret a écrit :
Cette formule doit exister, car sinon zpalm n'aurait pas d'aussi bon résultats avec une RPN !
En tout cas, elle doit dépendre des rapports entre les valeurs des pièces. Une forme canonique peut-être ?
Oui, j'aimerai bien voir la solution de zpalm. N'oublions pas non plus que la wp34s est très rapide comparée aux vieilles caltoches d'il y a 20-30 ans.


C.Ret a écrit :
Traduction de ce code en RPN :

Code : Tout sélectionner

« 1                                 // Initialise total
  0 100 FOR a                       //  Boucle 50c
     a 100 FOR b                    //    Boucle 20c
        b 100 FOR c                 //      Boucle 10c
           c 100 FOR d              //        Boucle 5c
              102 d – 2 / FLOOR +   //          Comptages 2c et 1c
           5 STEP                   //        5c 
        10 STEP                     //      10c
     20 STEP                        //    20c
  50 STEP                           //  50c
»
Sur l’HP-28S, on obtient 4563 en moins de 12 secondes soit moins de 2s de plus que les trucs CASIO compiqulés.
Sans l'optimisation dans la dernière boucle, l'équivalent du code de dprtl donne le résultat en 33 secondes sur une 48gx.
Avec l'optimisation dans la dernière boucle, le code ci-dessus donne le résultat en 5 secondes toujours sur une 48gx.
HP, Casio, Sharp, Psion, quelques TI et divers autres
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2934
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par zpalm »

bernouilli92 a écrit :
Gilles59 a écrit :L'algo de dprtl est vraiment très simple et très malin ! Et hyper rapide au passage ... je confirme qu'il donne le résultat correct, mais à vrai dire je ne comprends pas _pourquoi_ çà marche :O Je l'ai adapté 'bêtement'

Il y a là un subtilité mathématique qui m'echappe
...
Pareil , j'ai encore du mal à comprendre ce que cela fait exactement.
Je trouve cet algo beaucoup plus clair que certaines des solutions RPL récursives proposées …
bernouilli92 a écrit :
C.Ret a écrit :Cette formule doit exister, car sinon zpalm n'aurait pas d'aussi bon résultats avec une RPN !
En tout cas, elle doit dépendre des rapports entre les valeurs des pièces. Une forme canonique peut-être ?
Oui, j'aimerai bien voir la solution de zpalm. N'oublions pas non plus que la wp34s est très rapide comparée aux vieilles caltoches d'il y a 20-30 ans.
J'utilise 4 boucles: la même formule que dprtl plus l'astuce des pieces de 2c. J'attendais que vous ayez trouvé la formule avant de publier mon code :wink:

Une formule générale doit exister. J’essaye de la trouver …

WP 34S: 38 pas et 5 registres: 38*2+ 5*8 = 116 octets - donne 4563 en 13s

Code : Tout sélectionner

01  LBL A        20  X>=? 04
02  1            21  BACK 009
03  STO 00       22  #10
04  0            23  STO+ 03
05  STO 01       24  RDN
06  RCL 01       25  x>=? 03
07  STO 02       26  BACK 016
08  RCL 02       27  #20
09  STO 03       28  STO+ 02
10  RCL 03       29  RDN
11  STO 04       30  x>=? 02
12  #102         31  BACK 023
13  RCL- 04      32  #50
14  2            33  STO+ 01
15  IDIV         34  RDN
16  STO+ 00      35  x>=? 01
17  5            36  BACK 030
18  STO+ 04      37  RCL 00
19  #100         38  RTN
Et n’oubliez-pas la TI-57 ! :wink:
Avatar du membre
ledudu
Fonctionne à 14400 bauds
Fonctionne à 14400 bauds
Messages : 5646
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par ledudu »

Machine : Casio PB-2000c
Langage : Prolog
Trois paramètres :
- le nombre cherché C
- la somme R
- la pièce la plus haute autorisée :V

Code : Tout sélectionner

/* impasse - R<0 */
mpo(0,R,_):- <(R,0),!.
/* fin de branche de l'arbre - R=0*/
mpo(1,0,Z):-!.
/* pièces de 2*/
mpo(C,R,2):- C is 1+integer(R/2),!.
/* code récursif *\
valeur(3,5).
valeur(4,10).
valeur(5,20).
valeur(6,50).
valeur(7,100).
mpo(C,R,N):- valeur(N,V),S is R-V,mpo(D,S,N),O is N-1,mpo(E,R,O),C is D+E.

?-mpo(C,100,7).
C=4563
yes
?-mpo(C,50,3).
c=146
yes
Le sujet était très intéressant. Les premières versions ne fonctionnaient pas parce que le Prolog est très consommateur en mémoire RAM si on lui fait parcourir des arbres trop longs. J'ai traité le cas des pièces de 2 Cts à part.
La version proposée permet de moduler la somme cible et la valeur maximale de la pièce.
Ainsi, avec des pièces de 1, 2 et 5 cts il y a 146 combinaisons pour faire 50 cts.
Modifié en dernier par ledudu le 09 févr. 2013 10:48, modifié 13 fois.
Avatar du membre
dprtl
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 463
Enregistré le : 27 janv. 2013 00:26
Localisation : Strasbourg
Contact :

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par dprtl »

Après avoir recompilé ma version précédente avec Pure C sur Atari ST, j'ai eu envie de repasser un peu de temps avec l'excellent Basic 1000D de Jean-Jacques Labarthe. Le manuel est très riche, très instructif, même si certaines explications m'ont toujours laissé un peu perplexe. Et là surprise : en page 498, je tombe sur la solution du problème du Boulanger ! Le pourquoi du comment n'est pas très bien expliqué (pour l'auteur ça doit être évident), mais voici ce qu'on peut faire avec la fonction "taylor", vous allez en tomber sur le cul. Dans mon programme, j'ai juste écrit le long résultat dans un fichier pour pouvoir le recopier plus faciliement ici. Voici donc mes 3 lignes de code en Basic 1000D :

Code : Tout sélectionner

open "o",#1,"result"
print #1 taylor(1/[(1-x)*(1-x^2)*(1-x^5)*(1-x^10)*(1-x^20)*(1-x^50)*(1-x^100)],100)
close
Dans le résultat ci-dessous, seul le premier coefficient nous intéresse pour ce MPO, mais cet affichage représente les solutions pour tous les montants entre 1c et 1€ :

[4563*x^100 +4366*x^99 +4219*x^98 +4072*x^97 +3925*x^96 +3778*x^95 +3631*x^94 +3484*x^93 +3376*x^92 +3229*x^91 +3121*x^90 +2974*x^89 +2866*x^88 +2758*x^87 +2650*x^86 +2542*x^85 +2434*x^84 +2326*x^83 +2249*x^82 +2141*x^81 +2064*x^80 +1956*x^79 +1879*x^78 +1802*x^77 +1725*x^76 +1648*x^75 +1571*x^74 +1494*x^73 +1441*x^72 +1364*x^71 +1311*x^70 +1234*x^69 +1181*x^68 +1128*x^67 +1075*x^66 +1022*x^65 +969*x^64 +916*x^63 +881*x^62 +828*x^61 +793*x^60 +740*x^59 +705*x^58 +670*x^57 +635*x^56 +600*x^55 +565*x^54 +530*x^53 +508*x^52 +473*x^51 +451*x^50 +416*x^49 +394*x^48 +372*x^47 +350*x^46 +328*x^45 +306*x^44 +284*x^43 +271*x^42 +249*x^41 +236*x^40 +214*x^39 +201*x^38 +188*x^37 +175*x^36 +162*x^35 +149*x^34 +136*x^33 +129*x^32 +116*x^31 +109*x^30 +96*x^29 +89*x^28 +82*x^27 +75*x^26 +68*x^25 +61*x^24 +54*x^23 +51*x^22 +44*x^21 +41*x^20 +34*x^19 +31*x^18 +28*x^17 +25*x^16 +22*x^15 +19*x^14 +16*x^13 +15*x^12 +12*x^11 +11*x^10 +8*x^9 +7*x^8 +6*x^7 +5*x^6 +4*x^5 +3*x^4 +2*x^3 +2*x^2 +x +1]
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par Gilles59 »

ledudu a écrit :Machine : Casio PB-2000c
Langage : Prolog
Voilà ne machine originale Bravo :tongue: :tongue: (dommage qu'on n'ait pas le smiley clapclap )
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°34 (Tout à 1 Euro!)

Message par Gilles59 »

dprtl a écrit :Après avoir recompilé ma version précédente avec Pure C sur Atari ST, j'ai eu envie de repasser un peu de temps avec l'excellent Basic 1000D de Jean-Jacques Labarthe. Le manuel est très riche, très instructif, même si certaines explications m'ont toujours laissé un peu perplexe. Et là surprise : en page 498, je tombe sur la solution du problème du Boulanger !
Je n'ai qu'une chose à dire devant cette avalanche de petite monnaie : "My tailor is rich"

Ah le voilà notre 'petit' polynome ;) Taylor taylor, ca me rappelle mes cours de math çà ! La fonction existe sur HP50G (voir http://h20426.www2.hp.com/product/calcu ... Series.pdf ) mais limité à l'ordre 20 et donne
41*x^20 +34*x^19 +31*x^18 +28*x^17 +25*x^16 +22*x^15 +19*x^14 +16*x^13 +15*x^12 +12*x^11 +11*x^10 +8*x^9 +7*x^8 +6*x^7 +5*x^6 +4*x^5 +3*x^4 +2*x^3 +2*x^2 +x+1
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 : 5646
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par ledudu »

Gilles59 a écrit :
ledudu a écrit :Machine : Casio PB-2000c
Langage : Prolog
Voilà une machine originale Bravo :tongue: :tongue: (dommage qu'on n'ait pas le smiley clapclap )
Merci.
L'algorithme récursif est très proche de celui que tu as utilisé pour la HP-39GII.
Avatar du membre
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2934
Enregistré le : 03 mai 2008 15:33
Localisation : Grenoble

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par zpalm »

ledudu a écrit :
Gilles59 a écrit :
ledudu a écrit :Machine : Casio PB-2000c
Langage : Prolog
Voilà une machine originale Bravo :tongue: :tongue: (dommage qu'on n'ait pas le smiley clapclap )
Merci.
L'algorithme récursif est très proche de celui que tu as utilisé pour la HP-39GII.
Oulahh , pas courant le Prolog ... je ne comprends pas tout ce qui se passe dans ce programme. Félicitations ledudu !!!
dprtl a écrit :Après avoir recompilé ma version précédente avec Pure C sur Atari ST, j'ai eu envie de repasser un peu de temps avec l'excellent Basic 1000D de Jean-Jacques Labarthe. Le manuel est très riche, très instructif, même si certaines explications m'ont toujours laissé un peu perplexe. Et là surprise : en page 498, je tombe sur la solution du problème du Boulanger
Merci pour cette trouvaille, effectivement il y a bien une formule pour calculer le résultat mais je ne suis pas sur qu'un programme qui calcule le 100ème terme de la série de Taylor soit plus rapide et compact sur nos machines de poches que les solutions proposées précédemment...
Avatar du membre
Hobiecat
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3644
Enregistré le : 06 sept. 2011 14:57
Localisation : Normandie

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par Hobiecat »

zpalm a écrit :Merci pour cette trouvaille, effectivement il y a bien une formule pour calculer le résultat mais je ne suis pas sur qu'un programme qui calcule le 100ème terme de la série de Taylor soit plus rapide et compact sur nos machines de poches que les solutions proposées précédemment...
En fait ça dépend de la façon dont est calculé le coefficient de ce 100ème terme, mais j'avoue que mes souvenirs de Taylor sont bien trop lointains...
Okinawok
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 401
Enregistré le : 12 avr. 2011 15:07

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par Okinawok »

Salut,
Bon je suis une vraie tanche en programmation et je ne prétends pas lutter contre les supers programmes optimisés récursifs que vous avez présentés, et que souvent je ne comprends pas :lol: Cela dit le sujet m'a trotté dans la tête et m'a donné l'occasion de tester ma toute nouvelle TI-92+ dans la salle d'attente du médecin ce matin. J'avais apporté le gros manuel car j'avais oublié les structures de contrôle :lol: Ce n'est pas du tout optimisé, c'est même assez bourrin. Je me suis limité à trouver une solution , c'était mon objectif d'amateur :oops:

Bon alors ça donne bien 4563 en 2 mn 22 secondes approximativement.
n est le nombre de combinaisons possibles, b le nombre de pièce de 50 cts, c de 20 cts, ... J'avais introduit 'a' le nombre de pièces de 1 euros au début mais cela ne sert à rien :lol:

Le principe est de calculer le nombre de quintet (b,c,d,e,f) tels que la somme des pièces soit inférieure ou égale à 100 cts (puisque l'on peut compléter ensuite de toute façon par les 1 cts). On ajoute les pièces de 2 cte jusqu'à ce que l'on dépasse 1 euros. Ensuite quand on dépasse, on enlève les petites pièces et on met une grosse à la place. Et ainsi de suite ...

Code : Tout sélectionner

Prgm

0->b:0->c:0->d:0->e:0->f
0->n

While 50*b+20*c+10*d+5*e+2*f<=100
While 50*b+20*c+10*d+5*e+2*f<=100
While 50*b+20*c+10*d+5*e+2*f<=100
While 50*b+20*c+10*d+5*e+2*f<=100
While 50*b+20*c+10*d+5*e+2*f<=100
n+1->n
f+1->f
EndWhile
0->f:e+1->e
EndWhile
0->f:0->e:d+1->d
EndWhile
0->f:0->e:0->d:c+1->c
EndWhile
0->f:0->e:0->d:0->c:b+1->b
EndWhile
n+1->n
Disp n
EndPrgm
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par Gilles59 »

zpalm a écrit : Merci pour cette trouvaille, effectivement il y a bien une formule pour calculer le résultat mais je ne suis pas sur qu'un programme qui calcule le 100ème terme de la série de Taylor soit plus rapide et compact sur nos machines de poches que les solutions proposées précédemment...
Je pense aussi. ce n'est pas significatif,mais le CAS de la HP50 met 1,7 sec mais limité à 20 avec la fonction intégrée
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 : 5646
Enregistré le : 26 mars 2009 13:07
Localisation : Ile de France
Contact :

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par ledudu »

Je viens de relire les posts et je me rends compte qui'on est arrivé au même résultat chacun dans son coin, c'est à dire à traiter le cas très gourmand des pièces de 2 centimes à part (n=entier(reste/2)+1)..
Sans cette optimisation, Prolog n'arrive pas au bout.
Il donne enfin 4563 en 1 minute.
Prolog, c'est pas un rapide.
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3421
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par C.Ret »

PROLOG n'est pas rapide, mais il a bien d'autres avantages.

La remarque concernant la convergence des algorithmes est pertinente. Trouver une expression générale n'est pas facile, sauf effectivement pour les sommes composée à partir des pièces de 2c et 1c.

Les cas où s'ajoutent les pièces de 5c peuvent aussi être formalisés. On peut donc théoriquement économiser encore une des boucles emboîtées. A chaque fois que l'on ajoute une pièce de 5c, le nombre de combinaisons de pièce de 2c et 1c pour atteindre 1€ (c'est à dire 100c) diminue de 2.5 en moyenne:

Code : Tout sélectionner

             Nb 5c:   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19  20

    Somme composée:   0  5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
    Somme restante: 100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10  5   0

Combinaisons 2c 1c:  51 48 46 43 41 38 36 33 31 28 26 23 21 18 16 13 11  8  6  3   1
  
Cette suite est facilement programmable par exemple en utilisant l’arrondi INT(s/2.5).

Mais l’on peut faire disparaitre les autres boucles (celles des pièces 10c, 20c et 50c). En effet, les valeurs des pièces restantes sont toutes les trois multiples de 5c. Ce qui veut dire que quoi qu’il arrive, la suite de combinaison des pièces de 2c et 1c est toujours la même, quelque soit la composition des pièces de 5c, 10c, 20c ou 50c, au moment de calculer le nombre de combinaison on aura nécessairement affaire à l’une des 21 valeurs ci-dessus.

On peut donc, considérablement simplifier le problème en « factorisant » la décomposition.
En effet, chaque combinaison va être répétées un certains nombre de fois qui dépend directement du nombre d’arrangement possible des pièces de 5c, 10c, 20c et 50c pour composer la somme.

Or, trouver le nombre d’arrangement possible pour former une somme S avec les pièces { 5c 10c 20c et 50c}, cela ne revient-il pas à rechercher les combinaisons de pièces de [ 1x 2x 4x 10x ] pour former S/5 ?
De plus, ce nombre d’arrangement sera le même entre les somme D multiples de dix et D+5, car le arrangement possibles sont strictement identiques et ne diffèrent que par l’adjonction d’une pièce de 5c.

Code : Tout sélectionner

             Nb 5c:   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19  20

    Somme composée:   0  5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
    Somme restante: 100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10  5   0

Combinaisons 2c 1c:  51 48 46 43 41 38 36 33 31 28 26 23 21 18 16 13 11  8  6  3   1
Arrangements
          avec  5c:      1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1   1
          avec 10c:         1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9  10
          avec 20c:               1  1  2  2  5  5  6  6  9  9 12 12 16 16 21 21  35
          avec 50c:                                 1  1  2  2  4  4  6  6  8  8  13
           
             TOTAL:   1  1  2  2  4  4  6  6  9  9 13 13 18 18 24 24 31 31 39 39  49

      45631 = 51x1  + 48x1  + 46x2  + 43x2  + 41x4  + 38x4  + 36x6  + 33x6  + 31x9  + 28x9  + 26x13 _
            + 23x13 + 21x18 + 18x18 + 16x24 + 16x24 + 13x24 + 11x31 +  8x31 +  6x39 +  3x39 +  1x49.

D’où ma proposition pour un code n’utilisant qu’une seule boucle (allant de 0 à 20) parcourant les 21 combinaisons.

Code : Tout sélectionner

1 T=2,A=1,B=48,C=10,F=0:FOR D=0 TO 20
2 T=T+B*INT A,A=2.5+A,F=F+1:IF F LET C=C-(D<>16),B=B-C,F=-1
3 NEXT D:PRINT T
J’obtiens ainsi le résultat en moins de 20 s sur SHARP PC-1211 (pour 86 octets et 6 variables).

Et en moins de 4s sur HP-28C avec 183 octets :

Code : Tout sélectionner

« 2 (2.5,-10) (1,48)
  0 20 FOR d
     ROT OVER C->R SWAP IP * +
     ROT 
     IF
       d 2 MOD 
     THEN
       ROT OVER RE
     ELSE
       IF d 16 =/= THEN i ->NUM + END
       ROT OVER 
     END
     +
  NEXT
  DROP2
»
183 octets
Il reste encore de quoi optimiser !
Par ailleurs, cet algorithme ne me satisfait pas, car il n’est pas paramétrique. J’aurais préférer trouver quelque chose qui prenne en argument la somme 100 et la liste des pièces pour en déduire le nombre de combinaisons.

Par exemple, nous avons calculé le nombre de combinaisons pour obtenir 1€. Mais qu’en est-il du nombre de combinaisons pour 1£ ou 1$ sachant que dans ces monnaies, les pièces de 20c n’existent pas, mais que par-contre, il y a des pièces de 25c et 75c ?
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
dprtl
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 463
Enregistré le : 27 janv. 2013 00:26
Localisation : Strasbourg
Contact :

Re: Misez P'tit, Optimisez - N°34 (Tout à 1 Euro!)

Message par dprtl »

C.Ret a écrit : Par ailleurs, cet algorithme ne me satisfait pas, car il n’est pas paramétrique. J’aurais préférer trouver quelque chose qui prenne en argument la somme 100 et la liste des pièces pour en déduire le nombre de combinaisons.
Ton volume de travail est impressionnant sur ce MPO ! La performance (humaine) est réelle, mais effectivement, le fait de réaliser une sorte de "pré-calcul" nous éloigne un peu de l'algorithme universel... mais, après tout, pourquoi pas ? :wink:
Répondre

Retourner vers « Tous les Pockets »