problema del cajero, con entregar cambio dividido en diferentes cantidades
FunCambio(Precio: 10.28m, Paga: 50m);
Hay que poner la cantidad a abonar (precio) y el cantidad abonada(paga)
El algoritmo es este:
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;
List
<decimal> Cambio
= new List
<decimal>();
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
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;
List
<decimal> Cambio
= new List
<decimal>();
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.NETImports 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 (https://es.wikibooks.org/wiki/Programaci%C3%B3n_din%C3%A1mica/Problema_de_las_monedas_con_programaci%C3%B3n_din%C3%A1mica)