Jump to content

JAVA :: Math help


Recommended Posts

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 by mikem1034
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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...:)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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";
}

?>

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.