Pythagorean Triples Formula in Javascript - Project Euler Prob 9 - javascript

I'm trying to solve the Project Euler Problem 9 :
A Pythagorean triplet is a set of three natural numbers, a < b < c,
for which, a2 + b2 = c2
For example, 32 + 42 = 9 + 16 = 25 = 52.
There exists exactly one Pythagorean triplet for which a + b + c =
1000. Find the product abc.
I looked on Wikipedia for the formula to find Pythagorean triples and tried to translate it into code. The problem is that the code is outputting the wrong answer, but I think that the code is correct.
var a, b, c;
var pos1, pos2, pos3;
var ans1, ans2, ans3;
for(var n=2; n<=20000; n++) {
a = 2 * n + 1;
b = 2 * n * (n +1);
c = 2 * n * (n +1) + 1;
if(a<b<c) {
if(a^2 + b^2 === c^2) {
pos1 = a;
pos2 = b;
pos3 = c;
}
if(a + b + c ===1000) {
ans1 = a;
ans2 = b;
ans3 = c;
}
}
}
console.log(ans1 + " " + ans2 + " " + ans3);

This is a solution
var a;
var c;
for (var b = 1; b < 1000; b += 1) {
a = (500000 - 1000 * b) / (1000 - b);
if (Math.floor(a) === a) {
c = 1000 - a - b;
break;
}
}
console.log(a, b, c);
Result is 375 200 425
on jsfiddle
Pythagoras
a2 + b2 = c2
Also we have
a + b + c = 1000
algebra, rearrange c to left
c = 1000 - (a + b)
insert c back in pythagoras
a2 + b2 = (1000 - (a + b))2
multiply out
a2 + b2 = 1000000 - 2000 * (a + b) + (a + b)2
multiply out
a2 + b2 = 1000000 - 2000 * (a + b) + a2 + 2 * a * b + b2
rearrange a2 + b2 to simplify
0 = 1000000 - 2000 * (a + b) + 2 * a * b
rearrange unknowns to left
2000 * (a + b) - 2 * a * b = 1000000
simplify, / 2
1000 * (a + b) - a * b = 500000
factorsize
a(1000 - b) + 1000 * b = 500000
rearrange
a(1000 - b) = 500000 - 1000 * b
a = (500000 - 1000 * b) / (1000 - b)
now input b, calculate a and test if a is an integer as required by Pythagorean Triples

TGarr, here is an explanation to Xotic750's answer.
I don't really understand how you created the algorithm. Why is a = to (500000 - 1000 * b) / (1000 - b) ...
He started with a^2 + b^2 = c^2, and a + b + c = 1000, and combined them because the problem on projecteuler states that there is only 1 set of numbers where both of these statments will be true. Here's how he combined them. He solved the second equation for c to be c = 1000 - (a + b). Then he plugged that into the first equation so that it became a^2 + b^2 = (1000 - (a + b))^2. He continued until he was able to solve the entire equation for a. Once he was able to do that, he was able to make a single for loop that increases b, which is much simpler and more elegant than many other options.
why is the if statement's conditions set to Math.floor(a) === a?
This just means "is a, rounded down to its nearest integer, the same as a?" In other words, is a an integer? (copy his code, and add console.log ( a ); above the if statement. That might help you understand that bit of code) Since he was able to solve the equation for a, all he had to do was plug in different numbers for b, and as soon as the outcome was an integer, he'd have the answer. Or at least he'd know what a and b c = 1000 - a - b; tells him what c is, and that's all she wrote.

Here is another solution with less code:
for(var a = 1; a < 500; a++){
for(var b = a; b < 1000; b++){
var c = Math.sqrt(a * a + b * b);
if(c > b && Number.isInteger(c) && a + b + c == 1000){
console.log(a * b * c);
}
}
}
The result is: 31875000 :)

You can't calculate powers like that.
Use Math.pow(a,2) to calculate a^2
var a, b, c;
var pos1, pos2, pos3;
var ans1, ans2, ans3;
for(var n=2; n<=20000; n++) {
a = 2 * n + 1;
b = 2 * n * (n +1);
c = 2 * n * (n +1) + 1;
if(a<b<c) {
if(Math.pow(a,2) + Math.pow(b,2) === Math.pow(c,2)) {
pos1 = a;
pos2 = b;
pos3 = c;
}
if(a + b + c ===1000) {
ans1 = a;
ans2 = b;
ans3 = c;
}
}
}
console.log(ans1 + " " + ans2 + " " + ans3);

eq 1 : a2 + b2 = c2
eq 2 : a + b + c = 1000
From eq 1 and eq 2 we can have
eq 3 : c = 1000 - a - b
Substitute the value of c from eq 3 into eq 1 we get :
eq 4 : a2 + b2 = (1000 - a - b)2
R.H.S of eq 4 is a trinomial squared. We know that square of a trinomial of such kind is
(a - b - c)2 = a2 + b2 + c2 – 2ab + 2bc – 2ca
We get :
a2 + b2 = 10002 + a2 + b2 – 2*1000*a + 2*a*b – 2*b*1000
Now we simplify to get a to the L.H.S
a = (10002 - 2*1000*b)/(2*1000*b)
Now I can use this to find out value of a where it is an integer and then use Math.sqrt( aa + bb ) to calculate the value of c. Then I can check if a+b+c==1000 holds to be true.
My solution:
public class ProjectEuler9 {
public static void main(String[] args) {
long start = System.nanoTime();
double a;
for(int b=1; b<1000; b++){
a = ( (Math.pow(1000, 2) - 2000*b ) / (2000- 2*b) );
if(Math.floor(a) == a) {
// a is an integer
double c = Math.sqrt((a*a + b*b));
System.out.println("a : " + a + " b :" + b + " c : " + c);
long product = (long) (a*b*c);
System.out.println("product abc : " + product);
break;
} else {
//a is not an integer.
}
}
long stop = System.nanoTime();
System.out.println("\nTime: " + (stop - start) / 1000 + " ns");
}
}
Output :
a : 375.0 b :200 c : 425.0
product abc : 31875000
Time: 3714 ns

Related

pythagorean formula to calculate the perimeter of triangle in Javascript?

i am so newbie in programming. i had problem how to count the area and around of triangle.
i had code code some, but the output results are always wrong calculate.
function fungsiLuasSegitiga(a, b) {
var luas = (1 / 2) * a * b;
return luas;
}
function fungsiKllSegitiga(a, b) {
var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
var kll = a + b + c;
return kll;
}
var x = prompt("masukkan nilai alas segitiga!");
var y = prompt("masukkan nilai tinggi segitiga!");
var d = fungsiLuasSegitiga(x, y);
var e = fungsiKllSegitiga(x, y);
alert("luas segitiga adalah " + d);
alert("keliling segitiga adalah " + e);
when i put number 3 and 4, the function fungsiLuasSegitiga count it be 345, but the result must be 12 (3+4+5).
prompt returns a string and not a number. So, kll calculation ends up being "3" + "4" + 5. This concatenates the string instead of summing the numbers. You need to parse it to a number before assigning it to x and y either by using unary plus operator or parseInt
function fungsiLuasSegitiga(a, b) {
var luas = (1 / 2) * a * b;
return luas;
}
function fungsiKllSegitiga(a, b) {
var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
var kll = a + b + c;
return kll;
}
var x = +prompt("masukkan nilai alas segitiga!");
var y = +prompt("masukkan nilai tinggi segitiga!");
var d = fungsiLuasSegitiga(x, y);
var e = fungsiKllSegitiga(x, y);
alert("luas segitiga adalah " + d);
alert("keliling segitiga adalah " + e);

Calculating mean, min, max, sum of a list of integers - what's the complexity?

This is sort of a silly question that's been bugging me.
I have a list of 100k numbers that I am calculating some statistics for. Specifically, I am computing the mean, minimum, maximum, and sum of these numbers. I'm doing it using a fold. In JavaScript:
// define folding functions:
let mean = (a, b, index, array) => a + b / array.length
let max = (a, b) => Math.max(a, b)
let min = (a, b) => Math.min(a, b)
let sum = (a, b) => a + b
let fold = initial => f => data =>
Math.round(data.reduce(f, initial))
// functions we can consume:
let averageDistance = fold(0)(mean)
let maxDistance = fold(-Infinity)(max)
let minDistance = fold(Infinity)(min)
let totalDistance = fold(0)(sum)
// compute stats:
let data = [1, 2, 3, ...]
let a = averageDistance(data)
let b = maxDistance(data)
let c = minDistance(data)
let d = totalDistance(data)
The time complexity of this is clearly O(n) for each statistic averageDistance, maxDistance, etc. Computed over all 4 statistics, the complexity is O(4n).
Now, I can instead compute all 4 statistics in a single loop, using either a transducer (a similar optimization to Haskell's fusion), or by inlining eveything into a for loop:
let a = 0
let b = -Infinity
let c = Infinity
let d = 0
for (let i = 0; i < data.length; i++) {
a = mean(a, averageDistance(data[i]), i, data)
b = max(b, maxDistance(data[i]))
c = min(c, minDistance(data[i]))
d = sum(d, totalDistance(data[i]))
}
This solution only does a single loop, so intuitively it does it in O(n) time (an improvement over 4n from before).
But it still does the same amount of work as before: (100k integers)*(4 statistics) = 400k computations.
Is one solution really faster than another? Is the difference in space complexity (not in time)? If no to both of these, why bother with transducers or fusion at all?
This function:
Stats_A(array[1...n])
sum = 0
for i = 1 to n do
sum = sum + array[i]
avg = 0
for i = 1 to n do
avg = avg + array[i]
avg = avg / n
min = array[1]
for i = 1 to n do
if array[i] < min then
min = array[i]
max = array[1]
for i = 1 to n do
if array[i] > max then
max = array[i]
return (sum, avg, min, max)
And this function:
Stats_B(array[1...n])
sum = 0
min = max = array[1]
for i = 1 to n do
sum = sum + array[i]
if array[i] < min then
min = array[i]
else if array[i] > max then
max = array[i]
return (sum, sum / n, min, max)
Both have the same linear time complexity O(n). We can assign costs to basic operations and work out more details expressions for the time complexities of these functions, and then we will find that Stats_A does more work than Stats_B, but not asymptotically more work. We can let:
memory accesses (read/write) take time a
+, -, *, / take time b, c, d, e, respectively
comparisons (<, >, =) take time f
Now we can compute the more detailed runtime expressions:
This function:
Stats_A(array[1...n])
sum = 0 // a
for i = 1 to n do // a + n * (f + b + a)
sum = sum + array[i] // n * (2 * b + 3 * a)
// = (2 + 4 * n) * a
// + ( 3 * n) * b
// + ( 1 * n) * f
avg = 0 // a
for i = 1 to n do // a + n * (f + b + a)
avg = avg + array[i] // n * (2 * b + 3 * a)
avg = avg / n // 3 * a + e
// = (5 + 4 * n) * a
// + ( 3 * n) * b
// + ( 1 * n) * f
// + (1 ) * e
min = array[1] // 2 * a + b
for i = 1 to n do // a + n * (f + b + a)
if array[i] < min then // n * (2 * a + b + f)
min = array[i] // n * (2 * a + b)
// = (3 + 5 * n) * a
// + (1 + 3 * n) * b
// + ( 2 * n) * f
max = array[1] // 2 * a + b
for i = 1 to n do // a + n * (f + b + a)
if array[i] > max then // n * (2 * a + b + f)
max = array[i] // n * (2 * a + b)
// = (3 + 5 * n) * a
+ (1 + 3 * n) * b
+ ( 2 * n) * f
return (sum, avg, min, max) // = (5 ) * a
// total: (13 + 18 * n) * a
// + ( 2 + 12 * n) * b
// + ( 1 ) * e
// + ( 6 * n) * f
// = n * (18a + 12b + 6f) + (13a + 2b + e)
And this function:
Stats_B(array[1...n])
sum = 0 // a
min = max = array[1] // 3a + b
for i = 1 to n do // a + n * (f + b + a)
sum = sum + array[i] // n * (3 * a + 2 * b)
if array[i] < min then // n * (b + 2 * a + f)
min = array[i] // n * (b + 2 * a)
else if array[i] > max then // n * (b + 2 * a + f)
max = array[i] // n * (b + 2 * a)
return (sum, sum / n, min, max) // 5a + e
// total: ( 9 + 12 * n) * a
+ ( 1 + 7 * n) * b
+ ( 1 ) * e
+ ( 3 * n) * f
= n * (12a + 7b + 3f) + (9a + b + e)
The first function takes strictly longer than the second function; in the limit, the ratio of their runtimes approaches the quotient of their slopes:
(18a + 12b + 6f) / (12a + 7b + 3f)
We can observe that the denominator is strictly less than 2/3 of the numerator; therefore, the ratio is strictly greater than 3/2. We would expect, for any given input, Stats_A to take an amount approaching 50% longer than Stats_B as the input size increases without bound.

Having trouble converting a calculation in JavaScript

I am having trouble converting a calculation over into JavaScript. Any help would be greatly appreciated. Below please find an example of what I currently have.
Im having difficulty converting this into javascript:
(a * (1 + b) ^ c) + d * (((1 + b) ^ (c) - 1) / b)
Variables
var a = 1250;
var b = 0.03;
var c = 25;
var d = 3234;
var total = 0;
Method
var getTotal = function() {
var exponentBase = 1 + parseFloat(b);
total = a * (Math.pow(exponentBase, c)) + d *
((Math.pow(exponentBase, c) - 1) / b)
};
My getTotal comes up to 120526.48
But from what I am being told it should be 102297
Again any help would be greatly appreciated.
I'd rewrite the formula as:
(a * Math.pow((1 + b), c) + d * ((Math.pow((1 + b), c)) - 1) / b)
var aCalculation = function(a, b, c, d) {
var total = 0;
total = (a * Math.pow((1 + b), c) + d * ((Math.pow((1 + b), c)) - 1) / b);
return total;
};
console.log(aCalculation(1250, 0.03, 25, 3234));
Excel agrees:

Project Euler Solution 9 Code Not Working

function getAnswer(){
var answer, c = 334;
while (c < 999){
var a = Math.round(((1000 - c) / 2) - 0.5), b = Math.round((1000 - c) / 2);
while (a > 0 && b < c){
if (Math.pow(a, 2) + Math.pow(b, 2) != Math.pow(c, 2)){
a -= 1;
b += 1;
}else{
answer = a * b * c;
}
}
c += 1;
}
document.getElementById("a").innerHTML = answer;
}
Hi! I am a beginner programmer in javascript, and I have been trying to solve problem 9 in Project Euler. That problem goes like this:
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
I don't know why no answer appears, and my script crashes/program stops running, whenever I run this script. Please explain and tell me what's wrong with my script.
When you have found the answer, you don't stop with the iteration. Even worse, you don't change the values of a and b any more, so they never reach the end of the iteration, and you're stuck in an infinite loop.
You'll need to break out of the loop when you've found the answer. Or even break out of both your nested loops, using a label:
function getAnswer() {
var answer,
c = 334;
find: while (c < 999) {
var a = Math.round(((1000 - c) / 2) - 0.5),
b = Math.round((1000 - c) / 2);
while (a > 0 && b < c) {
if (Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2)) {
answer = a * b * c;
break find;
}
a -= 1;
b += 1;
}
c += 1;
}
document.getElementById("a").innerHTML = answer;
}
Notice that it would be easier if your function just returned the answer, instead of populating #a with it. You'd call it like
document.getElementById("a").innerHTML = getAnswer();
and can just return a * b * c; to break out of the whole function.

Refactor a for() loop using Math.pow()?

Here's a question that I'm hoping will improve my programming chops. I have this loop that is calculating a future sum based on annual payments, increased by interest and devalued by inflation (it's derived from the PV function in Excel):
var pmt = 66,449.75 // annual payment
var ip = 0.03 // interest rate
var fv = 0 // future value, not require here
var k = 1 // interest is applied at beginning / end of period
var n = 25 // number of periods (years in this case)
var ri = 0.025 // rate of inflation
var pv = 0;
for (var i = n - 1; i >= 0; i -= 1) {
pv = (pv + (pmt * k - fv) * Math.pow(1 + ri, i)) / (1 + ip);
}
Is it possible to use Math.pow() to reproduce what this loop is doing?
To simplify, I rename some expressions
a = pmt * k - fv;
b = 1 + ri;
c = 1 + ip;
x = pv;
So your code becomes
for (var i = n - 1; i >= 0; --i) {
x = x / c + a * Math.pow(b, i) / c;
}
Then
x_0
x_1 = x_0 / c + a b^{n-1} / c
x_2 = x_1 / c + a b^{n-2} / c = x_0 / c^2 + a b^{n-1} / c^2 + a b^{n-2} / c
...
x_i = x_{i-1} / c + a b^{n-i} / c = x_0 / c^i + \sum_{k=1}^i a b^{n-k} / c^{i-k+1}
...
x_n = x_0 / c^n + \sum_{k=1}^n a * b^{n-k} / c^{n-k+1}
According to WolframAlpha,
x_n = x_0 / c^n + a (b^n-c^n) / (c^n (b-c))
Therefore, instead of your loop you can use
var foo = Math.pow(1 + ip, n); // c^n
pv = pv / foo + (pmt*k-fv) * (Math.pow(1+ri,n) - foo) / foo / (ri-ip);

Categories

Resources