mikem1034 Posted January 16, 2013 Share Posted January 16, 2013 (edited) Hi! A friend of mine is trying to write a simulation of an ATM and can't seem to get it right. He want's it like so: If a user wants $100 and there are no $50 notes left, the machine gives them 5 $20 notes. Or if there is only 1 $50 note left in the machine and you want $100, it should dispence 1 x $50, 2 $20's and a $10. I dabbled in Java a few years ago but I tried to do this and have no idea. Maybe a variable to hole the amount of 50's, 20's and 10's in the machine? But after that I'm not sure. Does anyone know how to achieve this? In Java or PHP even? Thanks in advance! Edited January 16, 2013 by mikem1034 Quote Link to comment Share on other sites More sharing options...
Jessica Posted January 16, 2013 Share Posted January 16, 2013 Yes, it could be done in PHP. However, you've posted in client side help, which is typically HTML and Javascript. Java is a completely different language. Furthermore, it doesn't sound like you have any code to work with. If your friend is stuck on his Java code, he would probably get more help posting his code in a Java forum. If it's Javascript, he can post it here in our Javascript forum. But keep in mind no one is going to write it for him. He can get help figuring it out. Where do you live that ATMs have anything other than twenties? Quote Link to comment Share on other sites More sharing options...
cpd Posted January 16, 2013 Share Posted January 16, 2013 Ours have 5s and 10s . And just to defy Jessica completely, sorry, I went and did it myself for a bit of fun. Here's the test describing how it can be used and attached is an Eclipse archive. There's supposedly a more efficient method which would suit handling large quantities of notes. A friend was explaining if you divide all note values by 10 they become prime and from that you can begin to work out the lowest common factor of the requested amount and the available amount... I switched off to say the least. package com.dispenser.money; import java.util.Map; import java.util.TreeMap; import com.dispenser.money.AbstractMoneyDispenser.NotEnoughCashException; public class Test { public static void main(String[] args) { Map<MoneyType, Integer> startUpCash = new TreeMap<MoneyType, Integer>(); startUpCash.put(MoneyType.FIFTY, 3); startUpCash.put(MoneyType.TWENTY, 2); startUpCash.put(MoneyType.TEN, ; MoneyDispenser d = new MoneyDispenser(startUpCash); try { Wallet w = d.withdraw(170); System.out.println(w.toString()); System.out.println(d.toString()); } catch(NotEnoughCashException e) { e.printStackTrace(); } } } MoneyDispenser.zip Quote Link to comment Share on other sites More sharing options...
Jessica Posted January 16, 2013 Share Posted January 16, 2013 And just to defy Jessica completely, sorry, I went and did it myself for a bit of fun. And I have absolutely no problem with that I do it occasionally when something is challenging. But I have no idea if this person wanted PHP, Java, Javascript, or what. So... Quote Link to comment Share on other sites More sharing options...
Jessica Posted January 16, 2013 Share Posted January 16, 2013 Also I moved the topic since it's now Java. Quote Link to comment Share on other sites More sharing options...
shlumph Posted January 16, 2013 Share Posted January 16, 2013 I would make heavy use of division and the modulus operator, if writing the implementation from scratch http://php.net/manual/en/language.operators.arithmetic.php Quote Link to comment Share on other sites More sharing options...
Psycho Posted January 16, 2013 Share Posted January 16, 2013 I'm actually curious if the original question asked is the "right" question. It only gave a couple of examples using $100 as the requested amount. Are those really the only scenarios? Or, is it really a more general question of "When requesting money the machine will dispense using the largest available denominations". In that case it is necessary to know all the denominations the machine contains and the possible amounts that can be requested. Quote Link to comment Share on other sites More sharing options...
cpd Posted January 16, 2013 Share Posted January 16, 2013 That's where I struck a problem and my friend came along . I realised if you were to hypothetically ask the machine for £80 but it has only 2 £50 notes it can't fulfil your request. I never accounted for this so its not a perfect solution. It assumes there is a reasonable amount of each note in the machine to make the requested amount. Quote Link to comment Share on other sites More sharing options...
Psycho Posted January 16, 2013 Share Posted January 16, 2013 Just out of curiosity I decided to try and find a solution. It was much simpler than I thought. You would obviously need to have the "inventory" of the ATM with what denomination of bills are available and the quantities. Then you also have the requested amount. You simply need to loop through the available denominations from highest to lowest and determine how many of that denomination will "fit" within the requested amount and apply the minimum of that or the available quantity. You would also want a check at the end of the loop to determine if the requested amount was met (there may not be enough cash or the requested amount is not obtainable, e.g. $31). Here is a PHP solution. I made the $inventory a hard coded array for testing which would need to be dynamic.I also used global in the function (which I typically avoid) only for the purpose of brevity in the code - a class would probably be a better solution. <?php //Array pf possible denominations and their available qty $inventory = array( '50' => 3, '20' => 2, '10' => 5, '5' => 10 ); function getCurrency($requestAmt) { global $inventory; //Ensure inventory is from high to low denomination krsort($inventory); $distribution = array(); $newInventory = $inventory; foreach($newInventory as $denom => $quantity) { //Determine number of bill of this denom $denomQty = min($newInventory[$denom], floor($requestAmt/$denom)); //Update distribution and inventory $distribution[$denom] = $denomQty; $newInventory[$denom] -= $denomQty; //Reduce requested amount $requestAmt -= $denomQty * $denom; } //If unable to meet distribution, return error if($requestAmt != 0) { return false; } //Return distribution result (removing unused denoms) $inventory = $newInventory; return $distribution; } ################ ## TESTING LOGIC ################ $requestedAmounts = array(100, 32, 50, 25, 10, 50, 100, 20, 40); $header = "<tr><th></th>\n"; foreach(array_keys($inventory) as $denom) { $header .= "<th>\${$denom}</th>"; } $header .= "<th>Total</th></tr>\n"; foreach($requestedAmounts as $amt) { echo "<br><br><table border='1'>\n"; echo "<tr><th colspan='6'>Requested amount: $ {$amt}<th></tr>\n"; echo $header; displayCurrencyRow("Current Inventory", $inventory); $distribution = getCurrency($amt); if(!$distribution) { echo "<tr><td colspan='6'>Unable to fulfill request</td></tr>\n"; } else { displayCurrencyRow("Distributed Amount", $distribution); displayCurrencyRow("Remianing Inventory", $inventory); } echo "</table>\n"; } function displayCurrencyRow($label, $amounts) { $total = 0; echo "<tr>\n"; echo "<td>$label</td>\n"; foreach($amounts as $denom => $qty) { echo "<td>$qty</td>\n"; $total += $denom * $qty; } echo "<td>\${$total}</td>\n"; echo "<tr>\n"; } ?> Quote Link to comment Share on other sites More sharing options...
cpd Posted January 16, 2013 Share Posted January 16, 2013 On review I realised you can't do it any other way than I did, and as described above. I was thinking of ways to determine if the requested amount is divisible by the available notes but couldn't relate the requested amount to the amount of available notes. You can make it easier to work with by dividing the amounts by 10 but that's about it. I also looked into the bankers algorithm which describes what Physco has done and what I did. Quote Link to comment Share on other sites More sharing options...
Jessica Posted January 16, 2013 Share Posted January 16, 2013 FOR EVERYONE :-P Quote Link to comment Share on other sites More sharing options...
mikem1034 Posted January 19, 2013 Author Share Posted January 19, 2013 Thank you to everyone for the replies and suggestions. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.