poniedziałek, 31 marca 2014

Algorytm wydania reszty

Znów bawiłem się PS, decimalami i algorytmami. Dzisiaj zachłanny algorytm wydawania reszty z płatności.

function Solve-ChangeMaking 
{
    param(
        [ValidateNotNull()]
        [ValidateRange(0.01, 10000)]
        [decimal]$rest=.99,

        [ValidateNotNullorEmpty()]
        [ValidateScript({ 
        if($_ -lt 0.01 -OR $_ -gt 500)
        {
            throw "Not allowed nominations. Use nomination from 0.01 to  500"
        }
        return $true
        })]
        [array]$nominations =@(.99)
    )

    [array]$returnChange =@()
    [decimal]$remainedRest = $rest 
    $availableNominations = New-Object "System.Collections.Generic.List``1[decimal]"  
    #it should be 'list of deciaml' because problem with removeAt method
    $nominations | % { #adding nominations to list of decimals
        $availableNominations.Add($_)
    }

    $quantity = 0
    while($remainedRest -gt 0)
    {
        [decimal]$max = ($availableNominations | measure -Maximum).Maximum
        $index = $availableNominations.IndexOf($max);
        if($index -lt 0)
        {
            break
        }

        if($remainedRest -ge $max )
        {
            $remainedRest -= $max       
            $returnChange +=$max
            $quantity++
        }
        
        $availableNominations.RemoveAt($index)

        if($availableNominations.Count -eq 0)
        {
            break
        }
    }

    return  New-Object PSObject -Property @{ 
        Quantity  = $quantity; 
        'Remained Rest' =  $remainedRest;
        'Change to return'  = ($returnChange -join ' ');}
}

Do przetestowania algorytmu będziemy chcieli wydać resztę 97 groszy mając do dyspozycji 1, 2, 10, 20 i 50 groszy. Oczywiście zabraknie nam pieniędzy do wydania reszy:
Solve-ChangeMaking -rest .97 -nominations 0.10, 0.20, 0.50, 0.02, 0.01 

I wyniki:

Quantity : 5
Change to return : 0,5 0,2 0,1 0,02 0,01
Remained Rest : 0,14


Albo inny przykład z większą ilością gotówki:
$money = (20, 10, 5, 2, 1, .50, .20, .10, 0.05, .02, 0.01) *5 + 50 + 50
Solve-ChangeMaking -nominations $money -rest (200-0.99) 

A wyniki są następujące:

Quantity : 11
Change to return : 50 50 20 20 20 20 10 5 2 2 0,01
Remained Rest : 0,00

Brak komentarzy:

Prześlij komentarz