Robson » Little Red Book » Coinage analysis

Chapter 6 - Question 10

For an input sum of money, produce a list showing the number of notes and coins in each denomination needed to make up the sum, using the minimum number of each denomination and this the minimum number of notes and coins to produce the sum.

Solution 1

<?
   // randomly generate the amount of money to use
   // round money to two decimal places
   // for example: 1.88 / 87.57 / 42.00        
   $money = round(mt_rand(1, 10000) / 100, 2);
   
   // show the amount
   echo . number_format($money, 2) . '<br /> <br />';
   
   // the coins available in circulation
   // based on pounds sterling
   $available_currency = array(
       '0.01', '0.02', '0.05', '0.1', '0.2', '0.5', '1', '2', // coins
       '5', '10', '20', '50', '100' // notes
       );
       
   // checking should begin with the highest value, so reverse the array
   $available_currency = array_reverse($available_currency);
   
   // loop through all the available coins    
   for ($n = 0; $n < count($available_currency); $n++)
   {
       // reset the counter
       $counter = 0;
       // only loop while there is some money and the current coin/note could go into the amount
       while ($money && number_format($money, 2) >= number_format($available_currency[$n], 2))
       {
           // take away the current coin/note from the money
           $money -= $available_currency[$n];
           // increment the current counter which tracks how many of this coin/note have been used
           $counter++;
       }
       // if some of the current note/coin have been used
       if ($counter)
           // output the amount that was used and the number of times it was used
           echo . number_format($available_currency[$n], 2) . ' x' . $counter . '<br />';
   }
 
?>

Which produces:

9.45

5.00 x1
2.00 x2
0.20 x2
0.05 x1

Solution 2

Verbose version:

<?
   // returns an s when a number isn't one, used for showing plurals
   function plural($number)
   {
       // check if the number isn't one
       if ($number <> 1)
           // return an s to make the word a plural
           return 's';
   }
   // function to turn a number into a word
   // only works up to five (no need to go higher)
   function number_to_word($number)
   {
       // the first few numbers as words
       $words = array('zero', 'one', 'two', 'three', 'four', 'five');
       // return the corresponding number
       return $words[$number];
   }
 
   // randomly generate the amount of money to use
   // round money to two decimal places
   // for example: 1.88 / 87.57 / 42.00        
   $money = round(mt_rand(1, 10000) / 100, 2);
   
   // show the amount
   echo . number_format($money, 2) . ' are:<br /> <br />';
   
   // the coins available in circulation
   // based on pounds sterling
   $available_currency = array(
       '0.01', '0.02', '0.05', '0.1', '0.2', '0.5', '1', '2', // coins
       '5', '10', '20', '50', '100' // notes
       );
       
   // checking should begin with the highest value, so reverse the array
   $available_currency = array_reverse($available_currency);
   
   // loop through all the available coins    
   for ($n = 0; $n < count($available_currency); $n++)
   {
       // reset the counter
       $counter = 0;
       // only loop while there is some money and the current coin/note could go into the amount
       while ($money && number_format($money, 2) >= number_format($available_currency[$n], 2))
       {
           // take away the current coin/note from the money
           $money -= $available_currency[$n];
           // increment the current counter which tracks how many of this coin/note have been used
           $counter++;
           // this stores the amount of all coins/notes
           $total_counter++;
       }
       // if some of the current note/coin have been used
       if ($counter)
       {
           // check if it's a note
           if ($available_currency[$n] >= 5)
               // output the amount that was used and the number of times it was used
               echo ucfirst(number_to_word($counter)) . ' ' . $available_currency[$n] . ' pound note' . plural($counter) . '.<br />';
           // check if it's a type of pound coin (1 or 2)
           else if ($available_currency[$n] >= 1)
               // output the amount that was used and the number of times it was used
               echo ucfirst(number_to_word($counter)) . ' ' . $available_currency[$n] . ' pound coin' . plural($counter) . '.<br />';
           // all others, so must be pence
           else
               // output the amount that was used and the number of times it was used
               echo ucfirst(number_to_word($counter)) . ' ' . ($available_currency[$n] * 100) . ' pence coin' . plural($counter) . '.<br />';
           // output the amount remaining
           echo . number_format(abs($money), 2) . '<br />';
       }
   }
   // show how many coins/notes were used in total
   echo '<br />' . $total_counter . ' coin' . plural($total_counter) . '/note' . plural($total_counter) . ' were used in total.';
 
?>

Which produces:

The coins and notes needed to make 97.69 are:

One 50 pound note.
The amount remaining is 47.69
Two 20 pound notes.
The amount remaining is 7.69
One 5 pound note.
The amount remaining is 2.69
One 2 pound coin.
The amount remaining is 0.69
One 50 pence coin.
The amount remaining is 0.19
One 10 pence coin.
The amount remaining is 0.09
One 5 pence coin.
The amount remaining is 0.04
Two 2 pence coins.
The amount remaining is 0.00

10 coins/notes were used in total.

Log

© 2004-17 robson | cc unless stated