J'ai trouvé un morceau de code que j'écrivais pour la préparation de l'entrevue il y a quelques mois.
D'après le commentaire que j'ai eu, il essayait de résoudre ce problème:
Étant donné une certaine valeur en dollars en cents (par exemple 200 = 2 dollars, 1000 = 10 dollars), trouvez toutes les combinaisons de pièces qui composent la valeur en dollars. Seuls les centimes (1 ¢), les nickels (5 ¢), les dix sous (10 ¢) et les quarts (25 ¢) sont autorisés.
Par exemple, si 100 a été donné, la réponse devrait être:
4 quarter(s) 0 dime(s) 0 nickel(s) 0 pennies
3 quarter(s) 1 dime(s) 0 nickel(s) 15 pennies
etc.
Je pense que cela peut être résolu de manière itérative et récursive. Ma solution récursive est assez boguée, et je me demandais comment d'autres personnes pourraient résoudre ce problème. La partie difficile de ce problème était de le rendre aussi efficace que possible.
la source
code-golf
=> stackoverflow.com/questions/tagged/code-golfRéponses:
J'ai examiné cela une fois il y a longtemps, et vous pouvez lire mon petit article à ce sujet . Voici la source Mathematica .
En utilisant des fonctions de génération, vous pouvez obtenir une solution à temps constant de forme fermée au problème. Mathématiques concrètes de Graham, Knuth et Patashnik est le livre pour cela, et contient une discussion assez approfondie du problème. Essentiellement, vous définissez un polynôme où le n ème coefficient est le nombre de façons de faire un changement pour n dollars.
Les pages 4 à 5 de l'écriture montrent comment vous pouvez utiliser Mathematica (ou tout autre système d'algèbre informatique pratique) pour calculer la réponse pour 10 ^ 10 ^ 6 dollars en quelques secondes en trois lignes de code.
(Et c'était il y a assez longtemps que ça fait quelques secondes sur un Pentium 75Mhz ...)
la source
a
comme le domaine def
maisa = {1,5,10,25,50,100}
. Il devrait y avoir un 5 dans la liste des pièces de cent. Sinon, la rédaction était fantastique, merci!Remarque : cela montre uniquement le nombre de façons.
Fonction Scala:
la source
n1 * coins(0) + n2 * coins(1) + ... + nN * coins(N-1) = money
. Donc pourmoney=0
etcoins=List(1,2,5,10)
le nombre de combinaisons(n1, n2, n3, n4)
est 1 et la solution est(0, 0, 0, 0)
.money == 0
maiscoins.isEmpty
, cela ne devrait pas compter comme un sol'n. Par conséquent, l'algo peut être mieux servi si lacoins.isEmpty || money < 0
condition est satisfaite en premier.Je serais favorable à une solution récursive. Vous avez une liste de dénominations, si la plus petite peut diviser uniformément le montant restant en devise, cela devrait fonctionner correctement.
Fondamentalement, vous passez de la plus grande à la plus petite dénomination.
Récursivement,
Voici ma version python de votre problème déclaré, pour 200 cents. J'obtiens 1463 manières. Cette version imprime toutes les combinaisons et le total du comptage final.
la source
denominations
n'a pas1
comme dernière valeur. Vous pouvez ajouter une petite quantité de code auif
bloc le plus interne pour le corriger (comme je le décris dans ma réponse à l'autre question).Fonction Scala:
la source
Voici un code C ++ absolument simple pour résoudre le problème qui demandait que toutes les combinaisons soient affichées.
Mais je suis assez intrigué par le sous-problème de calculer simplement le nombre de combinaisons. Je soupçonne qu'il existe une équation de forme fermée pour cela.
la source
Le problème secondaire est un problème typique de programmation dynamique.
la source
Le code utilise Java pour résoudre ce problème et cela fonctionne également ... Cette méthode n'est peut-être pas une bonne idée à cause du trop grand nombre de boucles, mais c'est vraiment une méthode simple.
la source
C'est une question très ancienne, mais j'ai trouvé une solution récursive en java qui semblait plus petite que toutes les autres, alors voilà -
Améliorations:
la source
Soit C (i, J) l'ensemble des combinaisons de fabrication de i cents en utilisant les valeurs de l'ensemble J.
Vous pouvez définir C comme cela:
(first (J) prend de manière déterministe un élément d'un ensemble)
Cela s'avère une fonction assez récursive ... et raisonnablement efficace si vous utilisez la mémorisation;)
la source
semi-hack pour contourner le problème de combinaison unique - force l'ordre décroissant:
Cela fonctionnera lentement car il ne sera pas mémorisé, mais vous avez l'idée.
la source
la source
C'est ma réponse en Python. Il n'utilise pas la récursivité:
Exemple de sortie
la source
la source
Les deux: parcourir toutes les dénominations de haut en bas, prendre une dénomination, soustraire du total demandé, puis récurer sur le reste (contraindre les dénominations disponibles à être égales ou inférieures à la valeur d'itération actuelle.)
la source
Si le système monétaire le permet, un simple algorithme gourmand qui prend autant de pièces que possible, en commençant par la devise de valeur la plus élevée.
Sinon, une programmation dynamique est nécessaire pour trouver rapidement une solution optimale puisque ce problème est essentiellement le problème du sac à dos .
Par exemple, si un système monétaire a les pièces
{13, 8, 1}
:, la solution gourmande ferait le changement pour 24 comme{13, 8, 1, 1, 1}
, mais la vraie solution optimale est{8, 8, 8}
Edit: Je pensais que nous faisions des changements de manière optimale, sans énumérer toutes les façons de faire du changement pour un dollar. Mon récent entretien a demandé comment faire des changements, alors j'ai pris de l'avance avant de finir de lire la question.
la source
Je sais que c'est une question très ancienne. Je cherchais la bonne réponse et je n'ai rien trouvé de simple et satisfaisant. Cela m'a pris du temps mais j'ai pu noter quelque chose.
Ceci est une solution javascript et utilise la récursivité.
la source
Dans le langage de programmation Scala, je le ferais comme ceci:
la source
Il s'agit d'un simple algorithme récursif qui prend une facture, puis prend une facture plus petite de manière récursive jusqu'à ce qu'elle atteigne la somme, puis prend une autre facture de la même dénomination et se répète. Voir l'exemple de sortie ci-dessous pour l'illustration.
Imprime les éléments suivants:
la source
Duh, je me sens stupide en ce moment. Ci - dessous , il y a une solution trop compliquée, que je conserverai parce qu'il est une solution, après tout. Une solution simple serait la suivante:
Voici l'autre solution. Cette solution est basée sur le constat que chaque pièce est un multiple des autres, afin qu'elles puissent être représentées en fonction d'elles.
Donc, pour 37 pièces, par exemple:
la source
Cette entrée de blog résout ce problème de sac à dos pour les personnages d'une bande dessinée XKCD . Une simple modification du
items
dict et de laexactcost
valeur donnera également toutes les solutions à votre problème.Si le problème consistait à trouver le changement qui utilisait le moins de coût, alors un algorithme naïf avide qui utilisait autant de pièces de la plus grande valeur pourrait bien échouer pour certaines combinaisons de pièces et de montant cible. Par exemple, s'il y a des pièces avec les valeurs 1, 3 et 4; et le montant cible est de 6, alors l'algorithme gourmand pourrait suggérer trois pièces de valeur 4, 1 et 1 lorsqu'il est facile de voir que vous pouvez utiliser deux pièces chacune de valeur 3.
la source
la source
J'ai trouvé ce morceau de code dans le livre "Python For Data Analysis" par O'reily. Il utilise une implémentation paresseuse et une comparaison int et je suppose qu'il peut être modifié pour d'autres dénominations en utilisant des décimales. Faites moi savoir comment ça marche pour vous!
la source
C'est l'amélioration de la réponse de Zihan. Le grand nombre de boucles inutiles survient lorsque la valeur nominale n'est que de 1 cent.
C'est intuitif et non récursif.
la source
Solution Java simple:
la source
la source
Voici une fonction C #:
Utilisez-le comme ceci:
Il imprime:
la source
Voici un programme python pour trouver toutes les combinaisons d'argent. Il s'agit d'une solution de programmation dynamique avec un temps d'ordre (n). L'argent c'est 1,5,10,25
Nous passons de la ligne 1 à la ligne 25 (4 lignes). Row money 1 contient le décompte si l'on considère uniquement l'argent 1 dans le calcul du nombre de combinaisons. Row money 5 produit chaque colonne en prenant le compte dans la ligne money r pour le même argent final plus le compte 5 précédent dans sa propre ligne (position actuelle moins 5). L'argent en ligne 10 utilise l'argent en ligne 5, qui contient à la fois des comptes pour 1,5 et ajoute dans le compte 10 précédent (position actuelle moins 10). L'argent en ligne 25 utilise l'argent en ligne 10, qui contient les nombres pour l'argent en ligne 1,5,10 plus les 25 nombres précédents.
Par exemple, nombres [1] [12] = nombres [0] [12] + nombres [1] [7] (7 = 12-5) ce qui donne 3 = 1 + 2; nombres [3] [12] = nombres [2] [12] + nombres [3] [9] (-13 = 12-25) ce qui donne 4 = 0 + 4, puisque -13 est inférieur à 0.
la source
Solution Java
}
la source
La solution java ci-dessous qui imprimera également les différentes combinaisons. Facile à comprendre. L'idée est
pour somme 5
La solution est
Si la somme restante dans chaque boucle est inférieure à la dénomination, c'est-à-dire si la somme restante 1 est inférieure à 2, alors rompez simplement la boucle
Le code complet ci-dessous
Veuillez me corriger en cas d'erreur
}
la source
Voici une solution basée sur python qui utilise la récursivité ainsi que la mémorisation résultant en une complexité de O (mxn)
la source