Change and loops
Weekly challenge 236 — 25 September 2023
Week 236: 25 Sep 2023
You are asked to sell juice each costs $5. You are given an array of bills. You can only sell ONE juice to each customer but make sure you return exact change back. You only have $5, $10 and $20 notes. You do not have any change in hand at first. Write a script to find out if it is possible to sell to each customers with correct change.
Example 1 Input: @bills = (5, 5, 5, 10, 20) Output: true From the first 3 customers, we collect three $5 bills in order. From the fourth customer, we collect a $10 bill and give back a $5. From the fifth customer, we give a $10 bill and a $5 bill. Since all customers got correct change, we output true. Example 2 Input: @bills = (5, 5, 10, 10, 20) Output: false From the first two customers in order, we collect two $5 bills. For the next two customers in order, we collect a $10 bill and give back a $5 bill. For the last customer, we can not give the change of $15 back because we only have two $10 bills. Since not every customer received the correct change, the answer is false. Example 3 Input: @bills = (5, 5, 5, 20) Output: true
I think the easiest way to do this is just to mimic real life.
We start with nothing in the till.
A customer offering $5 can always be served.
A customer offering $10 can only be served if there is at least one $5 in the till.
A customer offering $20 can be served and given $10 + $5 from the till if that is possible, or 3 x $5 if that is possible, otherwise can't be served.
In each successful case the bill tendered by the customer gets added to the till, and we can check that the total in the till is always $5 x the number of customers served.
We might also note that even in this day of rapidly rising prices, $5 for a bottle of juice is rather steep. I suggest they'd all be better off going to Aldi.
#!/usr/bin/perl use v5.16; # The Weekly Challenge - 2023-09-25 use utf8; # Week 236 task 1 - Exact change use strict; # Peter Campbell Smith use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge exact_change(5, 5, 5, 10, 20); exact_change(5, 5, 10, 10, 20); exact_change(5, 5, 5, 20); exact_change(5, 5, 10, 20); sub exact_change { my (@bills, $bill, $change, @till, $ok, $explain, $j); # initialise @bills = @_; $ok = 'true'; # till starts empty $till[5] = $till[10] = $till[20] = 0; # loop over customers for $bill (@bills) { $explain .= qq[\n \$$bill paid]; $change = $bill - 5; # customer presents $5 - no change needed if ($change == 0) { $explain .= q[, no change due]; # customer presents $10 so give him $5 change if we have a $5 } elsif ($change == 5) { if ($till[5] > 0) { $till[5] --; $explain .= q[, $5 change]; } else { $ok = 'false'; # we don't } # customer presents $20 so give her a $10 and a $5, or 3 x $5 } elsif ($change == 15) { if ($till[10] > 0 and $till[5] > 0) { $till[10] --; $till[5] --; $explain .= q[, $10 + $5 change]; } elsif ($till[5] >= 3) { $till[5] -= 3; $explain .= q[, 3 x $5 change]; } else { $ok = 'false'; # we have neither } } # oh dear! unless ($ok eq 'true') { $explain .= q[, sorry, I don't have change]; last; } # add customer's payment to till $till[$bill] ++; $explain .= qq[, till now $till[5] x \$5, $till[10] x \$10 $till[20] x \$20 = \$] . ($till[5] * 5 + $till[10] * 10 + $till[20] * 20); } say qq[\nInput: \@bills = (] . join(', ', @bills) . ')'; say qq[Output: $ok$explain]; }
Input: @bills = (5, 5, 5, 10, 20) Output: true $5 paid, no change due, till now 1 x $5, 0 x $10 0 x $20 = $5 $5 paid, no change due, till now 2 x $5, 0 x $10 0 x $20 = $10 $5 paid, no change due, till now 3 x $5, 0 x $10 0 x $20 = $15 $10 paid, $5 change, till now 2 x $5, 1 x $10 0 x $20 = $20 $20 paid, $10 + $5 change, till now 1 x $5, 0 x $10 1 x $20 = $25 Input: @bills = (5, 5, 10, 10, 20) Output: false $5 paid, no change due, till now 1 x $5, 0 x $10 0 x $20 = $5 $5 paid, no change due, till now 2 x $5, 0 x $10 0 x $20 = $10 $10 paid, $5 change, till now 1 x $5, 1 x $10 0 x $20 = $15 $10 paid, $5 change, till now 0 x $5, 2 x $10 0 x $20 = $20 $20 paid, sorry, I don't have change Input: @bills = (5, 5, 5, 20) Output: true $5 paid, no change due, till now 1 x $5, 0 x $10 0 x $20 = $5 $5 paid, no change due, till now 2 x $5, 0 x $10 0 x $20 = $10 $5 paid, no change due, till now 3 x $5, 0 x $10 0 x $20 = $15 $20 paid, 3 x $5 change, till now 0 x $5, 0 x $10 1 x $20 = $20 Input: @bills = (5, 5, 10, 20) Output: true $5 paid, no change due, till now 1 x $5, 0 x $10 0 x $20 = $5 $5 paid, no change due, till now 2 x $5, 0 x $10 0 x $20 = $10 $10 paid, $5 change, till now 1 x $5, 1 x $10 0 x $20 = $15 $20 paid, $10 + $5 change, till now 0 x $5, 0 x $10 1 x $20 = $20
Any content of this website which has been created by Peter Campbell Smith is in the public domain