Need help porting this equation to java - java

I'm trying to make a program that calculates the required score to level in a game and the equation works fine on my calculator but not when i try changing it to work with java.
the equation is 5,000 / 3 * (4n^3 - 3n^2 - n) + 1.25 * 1.8^(n - 60) for example level 49 you should need to have a total score of 772240000 points and the calculator gives this answer but my java program doesn't. here is the code i tried.
for (int i = 0; i <= 100; i++) {
double score = (double) ((5000 / 3) * (Math.pow(4 * i, 3) - Math.pow(3 * i, 2) - i) + (1.25 * Math.pow(1.8, i - 60)));
System.out.println("Level " + i + " requires " + (long) score);
}
This doesnt seem to work right and gives 12513130000 as the required points for lvl 49. If anyone can get it to work would you miind explaining what i did wrong.

You're messing up your Math.pow calls, but you can avoid some of them entirely:
double score = (double) ((5000 / 3) * (4 * i * i * i - 3 * i * i - i) + (1.25 * Math.pow(1.8, i - 60)));
Here's what's wrong: Math.pow(4 * i, 3) is actually (4i)^3 and not 4(i^3). To do the latter, you would need the following:
4 * Math.pow(i, 3)
I'm not entirely sure about the integer division part (you are casting it to double), but you may have to change 5000 / 3 to 5000.0 / 3.

Your problem is inside Math.pow - you're multiplying your index value by a scalar each time.
4 * Math.pow(i, 3)
And
3 * Math.pow(i, 2)
Should fix it.
Edit: And the integer division mentioned in other answers.

Related

get dynamic ration for distrubution prize java

I have this algorithm that works, but I want to change it to have a dynamic ratio in order to have the distance of values for the first positions higher than those ones for the lastest positions.
So for instance if prize money = 1000, total_prizes = 5, last_prize = 50 I got:
1) 350.00
2) 275.00
3) 200.00
4) 125.00
5) 50.00
TOTAL SUM: 1000.00
What I would like to see should be:
1) 475.00
2) 250.00
3) 150.00
4) 75.00
5) 50.00
TOTAL SUM: 1000.00
Instead of having between positions always a fixed value of 75. Have an increase distance approaching the first positions, in this case
from 5) to 4) 25
from 4) to 3) 75
from 3) to 2) 100
from 2) to 1) 225
Here the current code:
public static void main(String[] aa){
float ratio;
float first_prize;
float s=0;
float money = 1000;
int total_prizes = 5;
float last_prize = 50;
float prizes[] = new float[total_prizes+1];
first_prize=2*(money/total_prizes)-last_prize; //last member of the progresion
ratio=(first_prize-last_prize)/(total_prizes-1);
prizes[total_prizes]=last_prize;
for (int j = total_prizes-1; j >=1; j--) {
prizes[j]=prizes[j+1]+ratio;
}
for(int k=1;k<=total_prizes;k++){
System.out.printf("%d) %.2f\n",k,prizes[k]);
s+=prizes[k];
}
System.out.printf("TOTAL SUM: %.2f\n",s);
}
Inside the loop:
for (int j = total_prizes-1; j >=1; j--) {
//ratio here should be calculated dynamically based on position...
prizes[j]=prizes[j+1]+ratio;
}
Thanks! :)
If I understand you, what you want is to have the following conditions:
Fixed total sum. In this case 1000.
Approximately a geometric ratio r with n terms. In this case 1.75.
All "round" numbers. In this case to the nearest 25.
I would suggest that you solve it by first creating an exact geometric sequence, and then tweak it to be round numbers.
The first step is easy because all geometric series with n terms look like this:
x + r * x + r^2 * x + ... + r^(n-1) * x
= x * (1 + r + r^2 + ... + r^(n-1))
= x * (1 + r + r^2 + ... + r^(n-1)) * (r - 1) / (r - 1)
= x * ((r - 1) + (r^2 - r) + (r^3 - r^2) + ... + (r^(n) - r^(n-1)) / (r - 1)
= x * (-1 + (r - r) + (r^2 - r^2) + ... + (r^(n-1) - r^(n-1)) + r^n) / (r - 1)
= x * (r^n - 1) / (r - 1)
So in we want
1000 = x * (r^n - 1) / (r - 1)
= x * (1.75^5 - 1) / (1.75 - 1)
= x * (16.4130859375 - 1) / 0.75
= 20.55078125 x
That gives us the following starting solution.
48.6599505797377
85.154913514541
149.021098650447
260.786922638282
456.377114616993
After that it is a question of tweaking those numbers up and down to get the answer that you want. There are a lot of ways you can do that. One is simply to start with the smallest and move it to a rounded number, and redistribute among the others in proportion to their weights, and continue. That gives you the following sequence of partial answers.
48.6599505797377
85.154913514541
149.021098650447
260.786922638282
456.377114616993
50
85.034965034965
148.811188811189
260.41958041958
455.734265734266
50
75
150.537634408602
263.440860215054
461.021505376344
50
75
150
263.636363636364
461.363636363636
50
75
150
275
450
This is not exactly your desired answer. But it is pretty darned close and hopefully acceptable as a strategy.
UPDATE I had tried 1.75 because it was close to (475/50)^(1/4). When I tried 1.8 instead I got your exact desired answer.
Furthermore note that we do not need to produce all of those intermediate answers. Each time we only need the smallest term. Which is given by target * (r-1) / (r^n - 1). Every time you find the smallest term, you subtract that from the target, reduce n by one, and repeat.

Java correct order of operations

I have written this operation on paper and it works just fine. I know that java the execution is from left to right and the precedence is like this; * / + - .
Java gives me a different result, but i cant figure out why.
public double overTimeWage() {
if (hours > 40) {
return (40 * baseRate) + (1.5 * baseRate)
* (hours - 40);
} else {
return 0;
}
}
Here's the inputs I'm using
int hours = 50;
double baseRate = 12;
as it stands it currently returns 660 , my expected return is 180.
I know this is the correct mathematical formula is because i worked it on paper. and i get 180 out of it.
660 is the expected return value. Your problem is that you added in an extraneous piece of the puzzle.
Judging by the name of your method, overTimeWage, it's supposed to calculate the amount of overtime of the worker, which is (overtimeMult * baseRate) * (hours - standardHours). In your case, (1.5 * baseRate) * (hours - 40).
The mathematical calculations go as follows:
(1.5 * baseRate) * (hours - 40)
(1.5 * 12 ) * (50 - 40)
(18 ) * (10 )
18 * 10
180
So we got the right answer, right? So why is your method returning 660 and not 180? Here's the thing, your method doesn't return (1.5 * baseRate) * (hours - 40). It returns (40 * baseRate) + (1.5 * baseRate) * (hours - 40).
See the problem? You're not returning the overtime earnings. You're returning their earnings for the whole day. Just to be clear, let's put this together again:
(40 * baseRate) + (1.5 * baseRate) * (hours - 40)
We already know that (1.5 * baseRate) * (hours - 40) = 180.
(40 * baseRate) + 180
(40 * 12) + 180
480 + 180
660
660. And there's your problem. It's the classic issue of code doing what you tell it to, not what you want it to.
If you just want the overtime:
return (1.5 * baseRate) * (hours - 40);
The way it's written for you, you're returning the ENTIRE pay, not just the overtime.

display monthly payment in pow(a,b) method

The formula to compute the monthly payment is as follows:
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate)numberOfYears x 12 ))
In the above formula, you have to compute (1 + monthlyInterestRate)numberOfYears x 12 ). The pow(a,b) method in the Java API Math class can be used to compute ab.
so how to put this in pow(a,b) method ?
The javadoc for the java.lang.Math class might help you here. Is there something specific you don't understand about that?
So the code to compute the b power of a should look something like this:
double result = Math.pow(a, b);
The formula you have does not look quite right. From Exact_formula_for_monthly_payment The formula should be
P= (L i)/(1- 1/(1+i)^n )
Where L is the loan amount, i is the monthly interest, and n number of periods. In your formula
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate)numberOfYears x 12 ))
the exponential sign has been missed out. I think you want
monthlyPayment = (loanAmount x monthlyInterestRate) / (1 – (1 / (1 + monthlyInterestRate) ^ (numberOfYears x 12) ))
To calculate this in java you would want
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 – (1 / Math.pow(1 + monthlyInterestRate,numberOfYears * 12)));
Which could be simplified to
monthlyPayment = (loanAmount * monthlyInterestRate) /
(1 – Math.pow(1 + monthlyInterestRate,-numberOfYears * 12));
using a negative exponent.

Printing a Sine Wave to the Console

I'm working on a Java program that prints a sine wave to the console. This is what I've written so far:
int num = 7;
for (double y = 2; y >= 0; y-=0.2) {
for (double x = 0; x <= num; x+=0.2) {
if ( ((0.1+x) >= Math.asin((double)y-1)) && (((double)x-0.1) <= Math.asin((double)y-1)) )
System.out.print('*');
else
System.out.print(' ');
}
System.out.println();
}
Essentially, this program treats each character on each line as a 0.2 x 0.2 area on a coordinate plane. If the sine function crosses this area, an asterisk is printed to the screen. Otherwise, a space is printed.
When run, this is printed to the console:
*
*
*
*
*
*
Can anybody tell me why my program stops after printing the first quarter of the wave?
The reason it only prints the first quarter of the sine wave is because of the indicated range of Math.asin:
Returns the arc sine of a value; the returned angle is in the range -pi/2 through pi/2.
Once you advance x past Math.PI / 2, then the if statement's condition will always be false.
You can take advantage of the fact that
sin(π - x) = sin(x)
and
sin(2π - x) = -sin(x)
by including more conditions. (I've also removed the unnecessary casts to double for clarity.)
if ( (0.1+x >= Math.asin(y-1)) && (x-0.1 <= Math.asin(y-1)) ||
(0.1+x >= Math.PI - Math.asin(y-1)) && (x-0.1 <= Math.PI - Math.asin(y-1))
(2*Math.PI -(0.1 + x) <= -Math.asin(y-1)) && (2*Math.PI -(x-0.1) >= -Math.asin(y-1)) )
Output:
*
* *
* *
* * *
* * *
* * *
* *
* *
* *
* *
*
The problem seems to arise from the condition of your if-statement, which almost always evaluates to false. You should check the calculus behind your conditional expression. I find increasing num does not really help here.
Maybe you should print another character instead of a whitespace by replacing System.out.print(' '); with System.out.print('_'); for instance. This way you may be able to figure out why your program behaves that way. Reworking that algorithm of yours may also be helpful.
Edit: Whoops, skimmed the code a little too fast. This is wrong.
Well, you set num to 7, then in your loop you take x from 0 to num-1, so you're only looping over 7 columns. Increase num and your graph should add additional columns. You'll have to increase the range of y values you loop over too, if you want the graph to extend to negative numbers.
However, your algorithm is extremely inefficient. You're calculating asin(y-1) twice for every square on your graph, when all you really need to do is calculate sin(x) once for every column. Why not just fill an array with precalculated sine values and then consult the array while drawing the graph? (I realize, of course, that on a modern computer it's fast enough to be practically irrelevant either way.)
Thank you all for the help! Based on #dasblinkenlight's suggestion to use sin instead of asin, I found a very simple solution:
int num = 7;
for (double y = 1; y >= -1; y-=0.2) {
for (double x = 0; x <= num; x+=0.2) {
double sin = Math.sin(x);
if ( (0.1+y) >= sin && (y-0.1) <= sin )
System.out.print('*');
else
System.out.print(' ');
}
System.out.println();
}
This prints this to the console:
*****
** *
* **
* * **
* * *
* * *
* *
* *
* *
** **
****

java code to compute some multiple of a number?

I am using Math.PI in my example, so it is a double. It is a simple code but there is a bit I am not sure how to do:
I want the code to calculate the fundamental period X of a sin or cos function with a multiplier value a given by the user. The n value is initialized at n=1 and is an integer value.
If the result of (2 * pi * n)/a = X is lower than pi then n should increment, and it should keep going until that number is a multiple of pi, then print the result.
Just to clarify: a is a multiplier of x which goes in the function sin or cos like this:
cos(ax)
sin(ax)
The bit I am having the trouble with is working out whether the number is a multiple of pi (provided it's already greater than pi, that is).
This is about as far as I got and it's incomplete.
public void printSinusoidalPeriod(double multiplier /* this would be `a` */){
double pi=Math.PI;
double p = (2 * pi * (double) n) / multiplier;
while(p<pi){
if(n%pi==0){
n=n+1;
System.out.println(n);
p = (2 * pi * (double) n) / multiplier;
}
}
p= (double)Math.round(p * 100) / 100;
System.out.println("period of function is = " + p + " and n = " + n);
}
It seems like it's not going into the if statement and getting caught in the while loop
If I understand your problem correctly, I had to solve a similar problem to this before using php. Not sure what the correct syntax is for javascript but maybe you should keep a counter that continues until (x/pi) is an integer which would indicate it is a multiple of pi..
I know this isn't the correct code but something like:
while (!isint(x/pi)) {
x++;
}
if (isint(x/pi)) {
//CODE TO EXECUTE
}
If I understand you correctly
while((2 * pi * n)/a)<pi)
{
if(!(n%pi==0))
{
n++;
}
}
multiple of y is the part you need to figure out yourself. but this should help you with the logic, If I have understood u correctly.
You appear to be calculating when
(2 * pi * n)/a = m * pi where m is some integer multiple.
so
2 * pi * n = m * pi * a
2 * n = m * a
n = m * a / 2
You other constraint is
(2 * pi * n)/a < pi
so
2 * pi * n < pi * a
2 * n < a
n < a / 2;
For both equations to be true, m must be an integer less than 1, but since you are starting at 1 for n it will never be true.
Ok here's how I did it in the end, with the help of the suggestions here.
public void printSinusoidalPeriod(double a){
double pi=Math.PI;
double p=m*pi;
while(n<a/2){
if((double)Math.round((n*pi)%pi)!=0.01){
n=n+1;
m = (int) Math.round(((2 * (double) n) / a));
p= (double)Math.round(m * pi * 100) / 100;
p=p*n;
}
}
System.out.println("period of function is = " + p + " and n = " + n);
System.out.println("Check: p/n = " + p/n);
}
Please let me know if you can spot any problems with the logic. I have not gone through many possibities yet, but the ones I did, looked okay to me.

Categories

Resources