Find the least number of coins required that can make any change from 1 to 99 cents

后端 未结 27 2269
生来不讨喜
生来不讨喜 2020-12-07 10:08

Recently I challenged my co-worker to write an algorithm to solve this problem:

Find the least number of coins required that can make any change from

27条回答
  •  北荒
    北荒 (楼主)
    2020-12-07 10:20

    A vb version

    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, _
                                  ByVal e As System.EventArgs) Handles Button1.Click
            For saleAMT As Decimal = 0.01D To 0.99D Step 0.01D
                Dim foo As New CashDrawer(0, 0, 0)
                Dim chg As List(Of Money) = foo.MakeChange(saleAMT, 1D)
                Dim t As Decimal = 1 - saleAMT
                Debug.WriteLine(t.ToString("C2"))
                For Each c As Money In chg
                    Debug.WriteLine(String.Format("{0} of {1}", c.Count.ToString("N0"), c.moneyValue.ToString("C2")))
                Next
            Next
        End Sub
    
        Class CashDrawer
    
            Private _drawer As List(Of Money)
    
            Public Sub New(Optional ByVal QTYtwoD As Integer = -1, _
                           Optional ByVal QTYoneD As Integer = -1, _
                           Optional ByVal QTYfifty As Integer = -1, _
                           Optional ByVal QTYquarters As Integer = -1, _
                           Optional ByVal QTYdimes As Integer = -1, _
                           Optional ByVal QTYnickels As Integer = -1, _
                           Optional ByVal QTYpennies As Integer = -1)
                _drawer = New List(Of Money)
                _drawer.Add(New Money(2D, QTYtwoD))
                _drawer.Add(New Money(1D, QTYoneD))
                _drawer.Add(New Money(0.5D, QTYfifty))
                _drawer.Add(New Money(0.25D, QTYquarters))
                _drawer.Add(New Money(0.1D, QTYdimes))
                _drawer.Add(New Money(0.05D, QTYnickels))
                _drawer.Add(New Money(0.01D, QTYpennies))
            End Sub
    
            Public Function MakeChange(ByVal SaleAmt As Decimal, _
                                       ByVal amountTendered As Decimal) As List(Of Money)
                Dim change As Decimal = amountTendered - SaleAmt
                Dim rv As New List(Of Money)
                For Each c As Money In Me._drawer
                    change -= (c.NumberOf(change) * c.moneyValue)
                    If c.Count > 0 Then
                        rv.Add(c)
                    End If
                Next
                If change <> 0D Then Throw New ArithmeticException
                Return rv
            End Function
        End Class
    
        Class Money
            '-1 equals unlimited qty
            Private _qty As Decimal 'quantity in drawer
            Private _value As Decimal 'value money
            Private _count As Decimal = 0D
    
            Public Sub New(ByVal theValue As Decimal, _
                           ByVal theQTY As Decimal)
                Me._value = theValue
                Me._qty = theQTY
            End Sub
    
            ReadOnly Property moneyValue As Decimal
                Get
                    Return Me._value
                End Get
            End Property
    
            Public Function NumberOf(ByVal theAmount As Decimal) As Decimal
                If (Me._qty > 0 OrElse Me._qty = -1) AndAlso Me._value <= theAmount Then
                    Dim ct As Decimal = Math.Floor(theAmount / Me._value)
                    If Me._qty <> -1D Then 'qty?
                        'limited qty
                        If ct > Me._qty Then 'enough 
                            'no
                            Me._count = Me._qty
                            Me._qty = 0D
                        Else
                            'yes
                            Me._count = ct
                            Me._qty -= ct
                        End If
                    Else
                        'unlimited qty
                        Me._count = ct
                    End If
                End If
                Return Me._count
            End Function
    
            ReadOnly Property Count As Decimal
                Get
                    Return Me._count
                End Get
            End Property
        End Class
    End Class
    

提交回复
热议问题