Choosing coins with least or no change given

前端 未结 8 1381
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-07 04:00

I am making a game which consists of coin denominations of $10, $5, $3, and $1. The player may have 0 or more of each type of currency in his inventory with a maximum of 15 coin

8条回答
  •  孤独总比滥情好
    2021-02-07 04:39

    This answer is based off of גלעד-ברקן's answer. I am posting it here as per his request. While none of the answers were quite the one that I was looking for I found that this was the best option posted. Here is the modified algorithm that I am currently using:

     $have){
                $error = ["error", "Insufficient Funds"];
                return $error;
        }
    
        $stack = [[0,$price,$have,[]]];
        $best = [-max($coin_value),[]];
    
        while (!empty($stack)){
    
                // each stack call traverses a different set of parameters
                $parameters = array_pop($stack);
    
                $i = $parameters[0];
                $owed = $parameters[1];
                $have = $parameters[2];
                $result = $parameters[3];
    
                if ($owed <= 0){
                        //NOTE: check for new option with least change OR if same as previous option check which uses the least coins paid
                        if ($owed > $best[0] || ($owed == $best[0] && (array_sum($result) < array_sum($best[1])))){
    
                                //NOTE: add extra zeros to end if needed
                                while (count($result) < 4){
                                        $result[] = 0;
                                }
                                $best = [$owed,$result];
                        }
                        continue;
                }
    
                // skip if we have none of this coin
                if ($inventory[$i] == 0){
                        $result[] = 0;
                        $stack[] = [$i + 1,$owed,$have,$result];
                        continue;
                }
    
                // minimum needed of this coin
                $need = $owed - $have + $inventory[$i] * $coin_value[$i];
    
                if ($need < 0){
                        $min = 0;
                } else {
                        $min = ceil($need / $coin_value[$i]);
                }
    
                // add to stack
                for ($j=$min; $j<=$inventory[$i]; $j++){
                        $stack[] = [$i + 1,$owed - $j * $coin_value[$i],$have - $inventory[$i] * $coin_value[$i],array_merge($result,[$j])];
                        if ($owed - $j * $coin_value[$i] < 0){
                                break;
                        }
                }
        }
    
        return $best;
    }
    

    Here is my test code:

    $start = microtime(true);
    
    $inventory = [0,1,3,4];
    $price = 12;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    
    
    $inventory = [0,1,4,0];
    $price = 12;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    $inventory = [0,1,4,0];
    $price = 6;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    
    $inventory = [0,1,4,0];
    $price = 7;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    
    $inventory = [1,3,3,10];
    $price=39;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    $inventory = [1,3,3,10];
    $price=45;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    //stress test
    $inventory = [25,25,25,1];
    $price=449;
    echo "\n";
    echo json_encode(leastChange($inventory,$price));
    echo "\n";
    
    $time_elapsed = microtime(true) - $start;
    echo "\n Time taken: $time_elapsed \n";
    

    The result:

    [0,[0,1,2,1]]
    
    [0,[0,0,4,0]]
    
    [0,[0,0,2,0]]
    
    [-1,[0,1,1,0]]
    
    [0,[1,3,3,5]]
    
    ["error","Insufficient Funds"]
    
    [-1,[25,25,25,0]]
    
    Time taken: 0.0046839714050293
    

    Of course that time is in microseconds and therefore it executed in a fraction of a second!

提交回复
热议问题