Work out change [fermé]

10

Vous écrivez un programme pour une caisse enregistreuse automatique. L'utilisateur doit changer avec le moins de pièces utilisées. Écrivez un programme qui prend un montant (disons 1,53 $) et donne des changements en coupures américaines - dans ce cas: 1 x billet d'un dollar, 1 x cinquante cents et 3 x un cent. Le programme le plus court sera le gagnant. Points bonus pour prendre en charge d'autres devises (par exemple, les dénominations britanniques) et les devises inhabituelles (1, 2, 3 cents?)

Vous avez ces dénominations américaines: 1 cent, 5 cents, 10 cents, 25 cents, 50 cents, 1 dollar (billet ou pièce), 2 dollars, 5 dollars, 10 dollars.

Vous avez ces dénominations britanniques: 1 pence, 2 pence, 5 pence, 10 pence, 20 pence, 50 pence, 1 £, 2 £, 5 £ (billet ou pièce), 10 £.

Thomas O
la source
3
Cela nécessite probablement un peu de clarification. Tout d'abord, vous devez probablement spécifier que nous voulons le moins de pièces (ce qui rend la question bonus légèrement plus intéressante, par exemple {1c, 49c, 50c} et 98c casse un algorithme naïf). Deuxièmement, un format d'entrée / sortie est utile. Des détails sur la gestion des valeurs non disponibles (pour les devises composées) seraient utiles. Enfin - vous voudrez peut-être énumérer les dénominations ici afin que les gens n'aient pas besoin de le rechercher s'ils ne le connaissent pas.
Nabb
Comment fonctionnent les points bonus? Juste s'il y a égalité pour le programme le plus court?
gnibbler
@gnibber, citant Stephen Fry: "[les points sont] déterminés de manière impartiale par un conseil en matière de service client sélectionné démographiquement, ventilé par âge et sexe - c'est-à-dire moi."
Thomas O
Je vais demander 50c car je n'ai pas encore vu de pièce de 50 cents. Mais ils existent apparemment
Martin York

Réponses:

2

Windows PowerShell, 108 111 117

Très première tentative, non golfée jusqu'à présent:

$i=+("$input"-replace'[^\d.]')
$args|%{0d+$_}|sort -des|%{$a=[math]::floor($i/$_)
if($a){$i-=$a*$_
"$a×$_"}}

Notes de mise en œuvre:

  1. Accepte la quantité à retourner via le pipeline
  2. Accepte la liste des coupures de devises via la ligne de commande
  3. La quantité peut être indiquée avec un symbole monétaire; qui sera supprimé (en fait, tout ce qui n'est pas numérique).
  4. La liste des dénominations n'a pas besoin d'être triée.
  5. Le programme produira la plus grande variation inférieure à la quantité demandée réalisable avec les dénominations données, soit 1,5 pour 1,53 si la pièce de 1 cent est manquante.

Si 3 et 4 n'ont pas besoin d'être satisfaits (c'est-à-dire que je contrôle le format d'entrée ;-)), alors le programme suivant suffit (71):

$i=+"$input"
$args|%{$a=[math]::floor($i/$_)
if($a){$i-=$a*$_
"$a×$_"}}
Joey
la source
2

Mathematica: 110 caractères

Sort[IntegerPartitions[Rationalize@#,Infinity,{10,5,2,1,1/2,1/4,1/10,5/100,1/100}],
    Length@#1<Length@#2&][[1]]&  

Usage

%[0.98]  
{1/100, 1/100, 1/100, 1/10, 1/10, 1/4, 1/2}  

Ou

Tally@Sort[IntegerPartitions[Rationalize@#,Infinity,
                             {10,5,2,1,1/2,1/4,1/10,5/100,1/100}],
     Length@#1<Length@#2&][[1]]&  

(6 caractères de plus) donne

{{1/100, 3}, {1/10, 2}, {1/4, 1}, {1/2, 1}}

Pour les autres dénominations, il suffit de changer le tableau des justifications {10, ...., 5 / 100,1 / 100}

Dr. belisarius
la source
2

D: 225 caractères

import std.algorithm,std.conv,std.stdio;void main(string[]args){auto m=args[1].findSplit(".");void p(T,S)(T t,T u,S s){foreach(v;[u,10,5,1]){writefln("%s %s%s",t/v,v,s);t-=(t/v)*v;}}p(to!int(m[0]),20,"");p(to!int(m[2]),25,"/100");}

Plus lisiblement:

import std.algorithm,std.conv,std.stdio;

void main(string[] a)
{
    auto m = a[1].findSplit(".");

    void p(T, S)(T t, T u, S s)
    {
        foreach(v; [u, 10, 5, 1])
        {
            writefln("%s %s%s", t / v, v, s);
            t -= (t / v) * v;
        }
    }

    p(to!int(m[0]), 20, "");
    p(to!int(m[2]), 25, "/100");
}

Ne gère que la devise américaine. Prend la valeur en tant que valeur à virgule flottante sur la ligne de commande (doit avoir le premier 0 pour les valeurs inférieures à 1 dollar). N'accepte pas $ comme partie de la valeur. Affiche le nombre de chaque type de billet / pièce sur une ligne distincte. Par exemple, une entrée de 1,53 entraîne:

0 20
0 10
0 5
1 1
2 25/100
0 10/100
0 5/100
3 1/100

Jonathan M Davis
la source
1

Mathematica, 51 octets

#~NumberDecompose~{10,5,2,1,.5,.25,.1,.05,.01}&

contribution

[1.53]

production

{0, 0, 0, 1, 1, 0, 0, 0, 3.}


Mathematica, 82 octets - AVEC BONUS--

(s=#~NumberDecompose~#2;Row@Flatten@Table[Table[#2[[i]]"+",s[[i]]],{i,Length@s}])&

Contribution

[37,6, {15, 7, 2,5, 1, 0,88, 0,2, 0,01}]

production

15 +15 +7 +0,2 +0,2 +0,2 +

J42161217
la source
Umm, cette question utilise des dénominations différentes du duplicata.
ericw31415
OP ne spécifie pas le format d'entrée / sortie.
J42161217
Cette question n'utilise pas de billets de 100 dollars et il n'y a pas de bonus.
ericw31415
ok.fixé et enregistré quelques octets! Quant au bonus, je vous prie de bien vouloir relire la question. Surtout la partie .. "Points bonus pour le support d'autres devises"
J42161217
Oups, je suppose que je n'ai pas vu ça alors!
ericw31415
1

Javascript, 84 83 octets

(n,v=[10,5,2,1,.5,.25,.1,.05,.01],l=[])=>{for(i in v)l[i]=n/v[i]|0,n%=v[i];return l}

(n,v=[10,5,2,1,.5,.25,.1,.05,.01],l=[])=>eval("for(i in v)l[i]=n/v[i]|0,n%=v[i];l")

Utilise un algorithme gourmand.

ericw31415
la source