3v4l.org

run code in 300+ PHP versions simultaneously
<?php function addBills(&$change, $value, $count) // add 'count' bills of 'value' to the 'change' array { $change = array_merge($change, array_fill(0, $count, $value)); } function removeBill(&$change, $value) // remove one bill of 'value' from the 'change' array { $key = array_search($value, $change); if ($key !== false) { unset($change[$key]); } } function getChangeTotal($change) // get the total vlaue of the 'change' array { return array_sum($change); } function findMinimum($bills, $wantedTotal, $change = []) { // without bills there's nothing to do if (count($bills) == 0) { return $change; } // get the next smaller bill $value = array_pop($bills); // how many of those will fit? $count = intdiv($wantedTotal - getChangeTotal($change), $value); if ($count > 0) { // add as many bills as will fit addBills($change, $value, $count); while ($count > 0) { // can we find more change? $change = findMinimum($bills, $wantedTotal, $change); // did we reach the wanted total? if ($wantedTotal == getChangeTotal($change)) { return $change; } else { // we have to use smaller bills $count--; removeBill($change, $value); } } } // try a smaller bill return findMinimum($bills, $wantedTotal, $change); } $bills = [2, 5, 10]; print_r(findMinimum($bills, 23)); /* $change = addBills([2,3], 4, 3); print_r($change); print_r(removeBill($change, 4)); */
Output for 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.25, 8.4.1 - 8.4.12
Array ( [0] => 10 [1] => 5 [2] => 2 [3] => 2 [4] => 2 [5] => 2 )

preferences:
68.56 ms | 406 KiB | 5 Q