Change and loops

Weekly challenge 236 — 25 September 2023

Week 236 - 25 Sep 2023

Task 1

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 1Input: @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 2Input: @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 3Input: @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

Peter Campbell Smith is hereby placed in the public domain