How can I use an array variable to IF statement? - java

I am developing a simple Taxi Meter Calculator system. I have no idea what to use to implement it. I have written a code but got stuck at IF statement where I had to insert an array variable. I am not sure whether this is the correct way to implement it.
This is the logic.
The first Km is 50/-.
Then the next 10Km will be charged 45/- per Km. eg : if 2km were gone
, charges would be 50/- + 45/- = 95/-, if 3km were gone 140/-.
The next 10km will be charged 35/- per km
25/- per km will be charged no matter how many kms gone after the above 10km exceed.
This is the code I have coded so far
private void btn_calActionPerformed(java.awt.event.ActionEvent evt) {
int kms1 = 50;
int kms2 = 45;
int kms3 = 35;
int kms4 = 25;
String[] firstkm={"3,4,5,6,7,8,9,10,11"};
if(txt_km.getText().equals("1")){
lblout.setText(""+kms1);
}
if(txt_km.getText().equals("2")){
lblout.setText(""+(kms1+kms2));
}if(txt_km.getText().equals(firstkm)){
int get = Integer.parseInt(txt_km.getText());
int rate = get+kms2;
lblout.setText(""+rate);
}
}
if there is any other method to solve this problem please mention it.

int fare = 0;
int distance = 0;
if (distance > 21) {
fare += (distance - 21) * 25;
distance = 21;
}
if (distance > 11) {
fare += (distance - 11) * 35;
distance = 11;
}
if (distance > 1) {
fare += (distance - 1) * 45;
distance = 1;
}
if (distance > 0) {
fare += distance * 50;
}
Then refactor by putting the magic numbers into arrays and loop through the arrays (4 times).

Here's a hint: Implement this method
/**
This method returns the amount a passenger must pay for this kilometer of their trip
*/
public int chargeForKilometer(int kilometerNumberInTrip) {
//...
}

try
String[] firstkm={3,4,5,6,7,8,9,10,11};
if(txt_km.getText().equals(firstkm[1])){
lblout.setText(""+kms1);
}
....

In case your conditions change and you want to avoid adding if conditions in your code, I wrote a configurable code.
public int calculateRate(int kmCount){
int baseRate = 50;
int[] stepRate = {45,35};
int step = 10;
int fare = 0;
int threshold = 21;
int beyondThresholdRate = 25;
if(kmCount>0){
fare = baseRate;
fare += (kmCount - threshold)<0?0:(kmCount - threshold)*beyondThresholdRate;
kmCount = kmCount - 1;
for(int i=0;i<=((kmCount/step) + (kmCount%step>0?1:0));i++){
fare += (kmCount/step)==0?(kmCount%step)*stepRate[i]:step*stepRate[i];
kmCount -=step;
if(i==stepRate.length-1) break;
}
}
return fare;
}
It is slightly complex, however, flexible.

Related

For loop in Java not working how I expected. Can someone help me out?

I have a loop in Java that is meant to calculate values for an array and put them in each index.
Here is what I have:
for(int i = 15; i <= 30; i += 5){
double rate = 0.03;
int index = 0;
payments[index] = LoanCalculator(initLoan, rate, i*12);
index++;
}
System.out.println();
System.out.printf("%-2.1f%c", 3.0, percent);
System.out.printf("%13.2f %9.2f %9.2f %9.2f", payments[0], payments[1], payments[2], payments[3]);
}
Here is what it outputs (note: there is other code that prints out the top portion of the output) :
Years: 15 20 25 30
__________________________________________________
3.0% 421.60 0.00 0.00 0.00
There is obviously a math error in here somewhere which is really bugging me because I passed the exact same parameters earlier and it was returning correct values.
What I am concerned with is that there are no values being placed in the last three indices. Can anyone explain to me what I have done wrong here?
P.S. Here is the LoanCalculator method I am using:
public static double LoanCalculator(double loan, double rate, int payments)
{
double r = rate/12;
double monPay = (loan * r * Math.pow(1+r, payments))/((Math.pow(1+r, payments))-1);
return monPay;
}
Any help is appreciated.
You are setting your index to 0 inside the loop. So only the first item is ever assigned.
You probably need:
int index = 0;
for (int year = 15; year <= 30; year += 5) {
payments[index++] = calculateLoan(initLoan, rate, year * 12);
}
Or better (in my opinion):
for (int i = 0; i < payments.length; i++) {
int year = i * 15;
int month = year * 12;
payments[i] = calcualteLoan(initLoan, rate, month);
}
Consider this code
for(int i = 15; i <= 30; i += 5){
double rate = 0.03;
int index = 0;
within your for loop your are re-setting index to zero each time
so the effect of
index++;
is nullified
Move the declaration of index to before your for loop
double rate = 0.03;
int index = 0;
for(int i = 15; i <= 30; i += 5){
payments[index++] = LoanCalculator(initLoan, rate, i*12);
}
You set index to 0 in your for-loop. This makes the loop reset the index each time you call it. The way to fix this would be to instantiate index above the loop and increment in the loop.

Sine using taylor series within a given tolerance

I am attempting to calculate the Sine function of an angle entered by the user in radians. I need to print the value within a given tolerance as well. I have spent a lot of time and am making very little progress. Any help would be greatly appreciated! Thanks! My main issue is a returning a value within the given tolerance.
// Tolerance is an epsilon value
ex. .00001
public static void sineCalc(double angle, double tolerance) {
int power = 1;
double currentAnswer = 0.0;
int count = 0;
double answer = 0.0;
double difference = 0.0;
int i = 1;
while (difference > tolerance || difference == 0) {
if (i % 2 == 0) {
currentAnswer = -Math.pow(angle, power) / getfactorial(power);
} else {
currentAnswer = Math.pow(angle, power) / getfactorial(power);
}
answer = answer + currentAnswer;
power = power + 2;
difference = Math.sin(angle) - answer;
difference = Math.abs(difference);
count++;
i++;
}
System.out.println(answer);
}

How to the "decision/path" during recursion?

I want to calculate the minimal costs in production by choosing lot sizes with recursion. The value I get is correct, but I also want to save the correct decisions/path(how much to produce in each period n). I don't know how to save it correctly. This way I just overwrite it everytime.
n = period, i = inventory, pcap = production capacity, demand[n] = how much i sell in period n,
Thanks!
public double getMinC(int n, int i) {
if(demand[n]-i > pcap) return Double.MAX_VALUE;
if(this.n == n) {
if(demand[n] < i) { //not sure if i need this
decision[n] = 0;
return storagecost * i-demand[n];
}
decision[n] = demand[n]-i;
return varc * demand[n]-i + fixc;
}
double min = Double.MAX_VALUE;
double cost = min;
int xmin = Math.max(0, demand[n] - i);
int xmax = Math.min(storagecap-i+demand[n], pcap);
int bestx = -1;
for(int x=xmin; x<=xmax; x++) {
cost = getMinC(n+1, i+x-demand[n]) + storagecost * (i+x-demand[n]);
if(x!=0) cost += fixc + varc * x;
if(cost< min) {
min = cost;
bestx = x;
}
}
decision[n] = bestx;
return min;
}
Your function should return both the value of the best decision along with the set of values that lead to that best solution. Something like:
struct solution {
double min;
int *decision;
}
This code:
cost = getMinC(n+1, i+x-demand[n]) + storagecost * (i+x-demand[n]);
if(x!=0) cost += fixc + varc * x;
if(cost< min) {
min = cost;
bestx = x;
}
should be changed to:
sol = getMinC(n+1, i+x-demand[n]) + storagecost * (i+x-demand[n]);
if(x!=0) cost += fixc + varc * x;
if ( sol.min< minsol.min) {
minsol.min = sol.min;
minsol.decision=malloc (n, sizeof (int));
minsol.decision [0]=x;
// Copy content of sol.decision into minsol.decision starting at index 1
}
...
...
return minsol;
Note that you need to take care of deallocating the returned solution structure and take care of allocating a new solution structure to be returned. A more efficient way would be to return a linked list instead of the array within the solution struct and append minx to the returned linked list of decisions.
This is in no way complete but I hope you got the idea.

How can I round down a decimal?

I am writing a program that will simulate a cash register change calculator. It should print the change and how to give back the change ( number of twenty, tens, fives, quarters, dimes, etc).
The problem is that when I compile the program, I get a big number. I've tried rounding it down but it doesn't work. ALSO, I don't know if it is caused by the change not being rounded but I won't get the number of cents, I only get 1 $10 bill.
p.s. I am taking a high school CS course and right now I can't use other methods of rounding it, I know there is a way like the one I attempted below (casting and stuff) which I am allowed to use at the moment.
Thank you.
public class changeCash
{
public static void main(String[] args)
{
double cost = 68.90;
double amtPaid = 80.00;
double change = 0;
int twentyBill= 0;
int tenBill = 0;
int fiveBill = 0;
int oneBill = 0;
int quarters = 0;
int dimes = 0;
int nickels = 0;
int pennies = 0;
change = amtPaid - cost;
change = ((int)change * 10) / 10.0;
System.out.println("Your change is " +"$" + change);
double back = amtPaid - cost;
if(back >= 20)
{
twentyBill++;
back -= 20;
System.out.println(twentyBill + " $20 bill(s)");
}
else if(back >= 10)
{
tenBill++;
back -= 10;
System.out.println(tenBill + " $10 bill(s)");
}
else if(back >= 5)
{
fiveBill++;
back -= 5;
System.out.println(fiveBill + " $5 bills(s)");
}
else if(back >= 1)
{
oneBill++;
back -= 1;
System.out.println(oneBill + " $1 bills(s)");
}
else if(back >= 0.25)
{
quarters++;
back -= 0.25;
System.out.println(quarters + " qaurter(s)");
}
else if(back >= 0.10)
{
dimes++;
back -= 0.10;
System.out.println(dimes + " dime(s)");
}
else if(back >= 0.05)
{
nickels++;
back -= 0.05;
System.out.println(nickels + " nickel(s)");
}
else if(back >= 0.01)
{
pennies++;
back -= 0.01;
System.out.println(pennies + " penny(ies)");
}
}
}
Couple of issues. First, smaller one:
change = amtPaid - cost;
Change is 11.1, as it should be, but then:
change = ((int)change * 10) / 10.0;
Casts take precedence over arithmetic, so first (int)change happens (which results in 11), then it is multiplied by 10, then divided by 10.0, and you end up with 11.0 instead of 11.1.
But your bigger problem is in your if statements. You have a series of if...else. Once one of these executes, the remainder of the else blocks will not. So when you have e.g.:
if (back >= 20) {
...
} else if (back >= 10) {
...
} else if (back >= 5) {
...
} else ...
As soon as one hits, it's done. If back >= 20 is false it goes to the next. Then if back >= 10 is true, it executes that, then doesn't execute the rest, so you would want to separate them, e.g.:
if (back >= 20) {
...
}
if (back >= 10) {
...
}
if (back >= 5) {
...
}
...
That'll get you closer, but you're still not quite there. For example, what if your change is 40? That will be two 20's. But your if statement will only take away a single 20. To that end, a while loop would be appropriate. It also more accurately reflects reality. In real life if you had to give somebody $40, you wouldn't just give them a single $20 and walk away, you'd get a dirty look. You'd keep giving them $20's until the amount you owed them was less than $20. So for example:
while (back >= 20) {
...
}
while (back >= 10) {
...
}
while (back >= 5) {
...
}
...
You want your code to reflect the logic you would use in reality.
Regarding your question in comments:
... why do I get $11.099999999999994 instead of just 11.1?
Floating-point rounding error. Decimal numbers are not 100% accurate; "11.1" can't be represented precisely. You have a couple of ways to work around it. You could round to two decimals when you display the number, e.g. System.out.printf("%.2f", change). However, you may want to use int and store the number of cents, rather than using double and storing the number of dollars. Working with integers is more precise, and actually, when working with currency in important applications, integers are often used for this reason.
Simpler Solution
double d = 2.99999999;
long l = (long) d;
Math.class, floor function
double d = Math.floor(2.55555) //result: 2.0
Returns the largest (closest to positive infinity) double value that
is less than or equal to the argument and is equal to a mathematical
integer
Find below the code which works well. Tested with different values. We want to avoid more than 2 decimal places hence I have added several utility methods just to do that.
Uncomment different cost values to see its working in different scenarios.
public class ChangeCash {
public static void main(String[] args) {
double cost = 65.90;
// cost = 68.33;
// cost = 42.27;
double amtPaid = 80.00;
double change = 0;
int twentyBill = 0;
int tenBill = 0;
int fiveBill = 0;
int oneBill = 0;
int quarters = 0;
int dimes = 0;
int nickels = 0;
int pennies = 0;
change = amtPaid - cost;
System.out.format("Your change is $ %.2f", decimalCeil(change, true));
System.out.println();
double back = decimalCeil(change, true);
if (back >= 20) {
twentyBill++;
back -= 20;
System.out.println(twentyBill + " $20 bill(s)");
}
if (back >= 10) {
tenBill++;
back -= 10;
System.out.println(tenBill + " $10 bill(s)");
}
if (back >= 5) {
fiveBill++;
back -= 5;
System.out.println(fiveBill + " $5 bills(s)");
}
if (back >= 1) {
oneBill = (int) (back * 10) / 10;
back -= oneBill;
System.out.println(oneBill + " $1 bills(s)");
}
if (decimalCeil(back) >= 0.25) {
quarters = (int) (back * 100) / 25;
back = correct2DecimalPlaces(back, 25);
System.out.println(quarters + " qaurter(s)");
}
back = (int) (decimalCeil(back, true) * 100);
if (back >= 10) {
dimes = (int) (back / 10);
back = back % 10;
System.out.println(dimes + " dime(s)");
}
if (back >= 5) {
nickels = (int) (back / 5);
back = back % 5;
System.out.println(nickels + " nickel(s)");
}
if (back >= 1) {
pennies = (int) back;
System.out.println(pennies + " penny(s)");
}
}
private static double correct2DecimalPlaces(double back, int modulo) {
int correctTwoPlaces = (int) (back * 100) % modulo;
back = (double) correctTwoPlaces / 100;
return back;
}
private static double decimalCeil(double change) {
int temp = (int) (change * 100);
double tempWithCeil = Math.ceil(temp);
double answer = tempWithCeil / 100;
return answer;
}
private static double decimalCeil(double change, boolean decimalThreePlaces) {
double temp = change * 1000;
double tempWithCeil = Math.ceil(temp);
double answer = tempWithCeil / 1000;
return answer;
}
}

Creating formula for distance and damage

public double getDamage(double distance){
int damage1 = 30; // (0 - 38.1)
int damage2 = 20; // (50.8 - *)
double range1 = 38.1;
double range2 = 50.8;
double damage = 0; // FORMULA
return damage;
}
I try to create a formula to calculate the amount of damage that has been effected by the distance.
(Variable Distance =)
0 till 38.1 metre It will return 30 damage.
50.8 till Inifite it will return 20 damage.
38.1 till 50.8 it will decrease linear 30 -> 20.
How can I make this method work?
Thanks in advance.
Sounds like this:
double x = (distance - range1) / (range2 - range1);
if (x < 0)
x = 0;
if (x > 1)
x = 1;
return damage1 + x * (damage2 - damage1);
Basically you follow a linear rule and also adjust to stay in your linear interval.
Looks like you want a step formula, not a linear formula. Step formula is basically a bunch of if-else if comparisons in code. Something like this:
public double getDamage(double dist){
if (0 < dist & dist < 38.1)
return 30;
else if ( 38.1 < dist & dist < 50.8 )
return 30 - dist/10;
else
return
}
Edit: just saw you do want it linearly between 38.1 and 50.8.
Use something like this return 30 - dist/10; dist/10 would give you damage of 27 to 23, you'd need to find an appropriate constant (instead of 10) yourself. (Which is easy since its y = mx + b and you have two points by your conditions (38.1, 30) and (50.8, 20). So sub those into y = mx+b and you'll get the formula to use in the 2nd else-if.
The formula you are looking for is a simple variation of the point-slop equation y = m(x-x1) + y1 equation, where m = (damage1 - damage2)/(range1 - range2), x1 = range1, y1 = damage1, and x is the variable distance.
public double getDamage(double distance){
int damage1 = 30;
int damage2 = 20;
double range1 = 38.1;
double range2 = 50.8;
double damage = 0;
if(0 <= distance && distance <= range1)
damage = damage1;
else if (range1 < distance && distance < range2)
damage = (damage1 - damage2)/(range1 - range2) * (distance - range1) + damage1;
else if (distance >= range2)
damage = damage2;
return damage;
}

Categories