Skip to content

Instantly share code, notes, and snippets.

@wodCZ
Forked from algb12/getChange.php
Last active September 17, 2016 18:42
Show Gist options
  • Save wodCZ/d033df8e804be6f19bc32830d663454f to your computer and use it in GitHub Desktop.
Save wodCZ/d033df8e804be6f19bc32830d663454f to your computer and use it in GitHub Desktop.
<?php
// This function takes an array of denominators for a currency and a sum, and returns an array describing the most efficient way to express the sum in terms of denominations.
// E.g. A sum, such as 200 EUR can be expressed in terms of 100x2, which is inefficient, as there is the denomination 200 for this job.
// The function will return the most efficient way to express the sum, not 100x2, but 200x1.
// Recommended to round both, the expected and actual value to 2 decimal places.
// FUNCTION
// getChange function
function getChange($sum, $denominations) {
// Initiate empty results array
$results = [];
rsort($denominations);
foreach ($denominations as $denomination) {
$frequency = (int)(floor(($sum) / $denomination));
$results[$denomination] = $frequency;
$sum = round($sum - ($denomination * $frequency), 2);
}
return $results;
}
// END FUNCTION
// Currency denominations for sample use and test
$denominations = ['500', '200', '100', '50', '20', '10', '5', '2', '1', '0.50', '0.20', '0.10', '0.05', '0.02', '0.01'];
// BEGIN TEST
// Error counter
$errors = 0;
// Number of iterations
$i = 888.88;
// Expected value is 0.00 from the start
$val_exp = 0.00;
while ($val_exp <= $i) {
// Call getChange function
$results = getChange($val_exp, $denominations);
// Reset calculated value;
$val_is = 0;
// Go through each denomination, add value to calculated total
foreach ($results as $denomination => $frequency) {
if ($frequency) {
$val_is += ($denomination * $frequency);
}
}
// Round both values, expected and actual, to 2 d.p.
$val_exp = round($val_exp, 2);
$val_is = round($val_is, 2);
// Increase error counter if difference detected
if ($val_is != $val_exp) {
$errors += 1;
}
// Increase expected value by 0.01
$val_exp += 0.01;
}
// Echo number of errors encountered
echo "$errors errors encountered for $i iterations<br><br>";
// END TEST
// SAMPLE USE
$sum = 372.37;
$results = getChange($sum, $denominations);
echo "Best way to return change for $sum:<br><br>";
foreach ($results as $denomination => $frequency) {
if ($frequency) {
echo "$frequency times " . round($denomination, 2) . " EUR<br>";
}
}
// END SAMPLE USE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment