Código
FunCambio(Precio: 10.28m, Paga: 50m);
Hay que poner la cantidad a abonar (precio) y el cantidad abonada(paga)
El algoritmo es este:
Código
decimal Precio = 12.28m; decimal Paga = 50m; int[] Euros = { 2, 1 }; decimal[] Centimos = { 0.5m, 0.2m, 0.1m, 0.05m, 0.02m, 0.01m }; if (Precio <= Paga) { decimal Devolver = Paga - Precio; while (Devolver >= 1) { foreach (int Moneda in Euros) { if (Devolver >= Moneda) { Devolver -= Moneda; Cambio.Add(Moneda); break; } } } while (Devolver > 0) { foreach (decimal Moneda in Centimos) { if (Devolver >= Moneda) { Devolver -= Moneda; Cambio.Add(Moneda); break; } } }
'Cambio' es un array lista que devuelve una lista ´tipo "2, 2, 2, 2, 1 ,0.5, 0.02" que son lo tipos de moneda a devolver ya optimizado.
EJEMPLO
Código
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { FunCambio(Precio: 10.28m, Paga: 50m); } private void Form1_Load(object sender, EventArgs e) { } /// <summary> /// Calcula el número óptimo de monedas a devolver /// </summary> /// <param name="Precio">Total a abonar</param> /// <param name="Paga">Total abonado</param> public void FunCambio(decimal Precio, decimal Paga) { // decimal Precio = 12.28m; // decimal Paga = 50m; int[] Euros = { 2, 1 }; decimal[] Centimos = { 0.5m, 0.2m, 0.1m, 0.05m, 0.02m, 0.01m }; if (Precio <= Paga) { decimal Devolver = Paga - Precio; while (Devolver >= 1) { foreach (int Moneda in Euros) { if (Devolver >= Moneda) { Devolver -= Moneda; Cambio.Add(Moneda); break; } } } while (Devolver > 0) { foreach (decimal Moneda in Centimos) { if (Devolver >= Moneda) { Devolver -= Moneda; Cambio.Add(Moneda); break; } } } //MUESTRA EL RESULTADO string Resultado = null; int n2E = 0; int n1E = 0; int n50c = 0; int n20c = 0; int n10c = 0; int n5c = 0; int n2c = 0; int n1c = 0; decimal TotalADevolver = Paga - Precio; foreach (decimal Mda in Cambio) { switch (Convert.ToString(Mda)) { case "2": n2E += 1; break; case "1": n1E += 1; break; case "0,5": n50c += 1; break; case "0,2": n20c += 1; break; case "0,1": n10c += 1;break; case "0,05":n5c += 1;break; case "0,02":n2c += 1;break; case "0,01":n1c += 1;break; } } Resultado = string.Format("Precio: {1:0.00}€{0}" + "Cantidad abonada: {2:0.00}€{0}" + "Total a devolver: {3:0.00}€{0}{0}" + "CAMBIO{0}" + "2€: {4}{0}" + "1€: {5}{0}" + "50 céntimos: {6}{0}" + "20 céntimos: {7}{0}" + "10 céntimos: {8}{0}" + "5 céntimos: {9}{0}" + "2 céntimos: {10}{0}" + "1 céntimos: {11}{0}", Environment.NewLine, Precio, Paga, TotalADevolver, n2E, n1E, n50c, n20c, n10c, n5c, n2c, n1c); MessageBox.Show(Resultado); } else { MessageBox.Show("El valor abonado es inferior al total a pagar"); } } } }
Se mostrará un mensaje con el resultado de las monedas a devolver como cambio.
VB.NET
Código
Imports System.Text Public Class Form1 Friend WithEvents Button2 As New Button Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click FunCambio(Precio:=5.2, Paga:=50) End Sub Public Sub FunCambio(ByVal Precio As Decimal, ByVal Paga As Decimal) Dim Euros() As Integer = {2, 1} Dim Centimos() As Decimal = {0.5, 0.2, 0.1, 0.05, 0.02, 0.01} If Precio <= Paga Then Dim Devolver As Decimal = Paga - Precio 'Total a devolver Dim Cambio As New List(Of Decimal) 'Lista de cambio recibido While Devolver >= 1 For Each Moneda As Integer In Euros If Devolver >= Moneda Then Devolver -= Moneda Cambio.Add(Moneda) Exit For End If Next End While While Devolver > 0 For Each Moneda As Decimal In Centimos If Devolver >= Moneda Then Devolver -= Moneda Cambio.Add(Moneda) Exit For End If Next End While 'Muestra el resultado Dim Resultado As String Dim n2E, n1E, n50c, n20c, n10c, n5c, n2c, n1c As Integer Dim TotalADevolver As Decimal = Paga - Precio For Each N As Decimal In Cambio.ToList Select Case N Case 2D : n2E += 1 Case 1D : n1E += 1 Case 0.5D : n50c += 1 Case 0.2D : n20c += 1 Case 0.1D : n10c += 1 Case 0.05D : n5c += 1 Case 0.02D : n2c += 1 Case 0.01D : n1c += 1 End Select Next Resultado = String.Format("Precio: {1:0.00}€{0}" & "Cantidad abonada: {2:0.00}€{0}" & "Total a devolver: {3:0.00}€{0}{0}" & "CAMBIO{0}" & "2€: {4}{0}" & "1€: {5}{0}" & "50 céntimos: {6}{0}" & "20 céntimos: {7}{0}" & "10 céntimos: {8}{0}" & "5 céntimos: {9}{0}" & "2 céntimos: {10}{0}" & "1 céntimos: {11}{0}", Environment.NewLine, Precio, Paga, TotalADevolver, n2E, n1E, n50c, n20c, n10c, n5c, n2c, n1c) MessageBox.Show(Resultado) Else MessageBox.Show("El valor abonado es inferior al total a pagar", "Atención", Nothing, MessageBoxIcon.Exclamation) End If End Sub End Class
Más info:
https://es.wikibooks.org/wiki/Programaci%C3%B3n_din%C3%A1mica/Problema_de_las_monedas_con_programaci%C3%B3n_din%C3%A1mica