Computing the volume of a regular tetrahedron with edge length - javascript

Im trying to figure out how to write a JavaScript program that computes and outputs the volume of a regular tetrahedron. This is how far I got but it seems to get a error and not compute the right numbers after.
The equation for the triangle is
v = a3
6 √ 2
Sorry about the code i dont know how to post things on here very effectively. So this is my variables
var a = parseFloat(document.getElementById('length').value);
var b = (a * a * a) / 6 * Math.sqrt(2)

You are very close. You are missing some parenthesis around 6 * Math.sqrt(2)
Your code is doing (a*a*a) / 6 and then multiplying that result by the square root of 2.
You can read up on Operator Precedence
var a = 4;
var b = (a * a * a) / (6 * Math.sqrt(2))
console.log(b);
You can also use Math.pow()
var a = 4;
var b = Math.pow(a,3) / (6 * Math.sqrt(2))
console.log(b);

Related

Function with multiple possible arguments that will never return the same value given any sequence of arguments

Let's say you have a function that takes both x and y, real numbers that are integers, as arguments.
What would you put inside that function, using only mathematical operators, so that no two given sequences of arguments could ever return the same value, be it any kind of value?
Example of a function that fails at doing this:
function myfunction(x,y){
return x * y;
}
// myfunction(2,6) and myfunction(3,4) will both return 12
// myfunction(2,6) and myfunction(6,2) also both return 12.
As already noted in comments, at the level of JavaScript numbers such a function can't exist, simply because assuming that we're working with integer-valued IEEE 754 binary64 floats there are more possible input pairs than possible output values.
But to the mathematical question of whether there is a simple, injective function from pairs of integers to a single integer, the answer is yes. Here's one such function that uses only addition and multiplication, so should fit the questioner's "using only mathematical operators" constraint.
First we map each of the inputs from the domain of integers to the domain of nonnegative integers. The polynomial map x ↦ 2*x*x + x will do that for us, and maps distinct values to distinct values. (Sketch of proof: if 2*x*x + x == 2*y*y + y for some integers x and y, then rearranging and factoring gives (x - y) * (2*x + 2*y + 1) == 0; the second factor can never be zero for integers x and y, so the first factor must be zero and x == y.)
Second, given a pair of nonnegative integers (a, b), we map that pair to a single (nonnegative) integer using (a, b) ↦ (a + b)*(a + b) + a. It's easy to see that this, too, is injective: given the value of (a + b)*(a + b) + a, I can recover the value of a + b by taking the integer square root, and from there recover a and b.
Here's some Python code demonstrating the above:
def encode_pair(x, y):
""" Encode a pair of integers as a single (nonnegative) integer. """
a = 2*x*x + x
b = 2*y*y + y
return (a + b)*(a + b) + a
We can easily check that there are no repetitions for small x and y: here we take all pairs (x, y) with -500 <= x < 500 and -500 <= y < 500, and find the set containing encode_pair(x, y) for each combination. If all goes well, we should end up with a set with exactly 1 million entries, one per input combination.
>>> all_outputs = {encode_pair(x, y) for x in range(-500, 500) for y in range(-500, 500)}
>>> len(all_outputs)
1000000
>>> min(all_outputs)
0
But perhaps a more convincing way to establish the injectivity is to give an explicit inverse, showing that the original (x, y) can be recovered from the output. Here's that inverse function. It makes use of Python's integer square root operation math.isqrt, which is available only for Python >= 3.8, but is easy to implement yourself if you need it.
from math import isqrt
def decode_pair(n):
""" Decode an integer produced by encode_pair. """
a_plus_b = isqrt(n)
a = n - a_plus_b*a_plus_b
b = a_plus_b - a
c = isqrt(8*a + 1)
d = isqrt(8*b + 1)
return ((2 - c%4) * c - 1) // 4, ((2 - d%4) * d - 1) // 4
Example usage:
>>> encode_pair(3, 7)
15897
>>> decode_pair(15897)
(3, 7)
Depending on what you allow as a "mathematical operator" (which isn't really a particularly well-defined term), there are tighter functions possible. Here's a variant of the above that provides not just an injection but a bijection: every integer appears as the encoding of some pair of integers. It extends the set of mathematical operators used to include subtraction, division and absolute value. (Note that all divisions appearing in encode_pair are exact integer divisions, without any remainder.)
def encode_pair(x, y):
""" Encode a pair of integers as a single integer.
This gives a bijective map Z x Z -> Z.
"""
ax = (abs(2 * x + 1) - 1) // 2 # x if x >= 0, -1-x if x < 0
sx = (ax - x) // (2 * ax + 1) # 0 if x >= 0, 1 if x < 0
ay = (abs(2 * y + 1) - 1) // 2 # y if y >= 0, -1-y if y < 0
sy = (ay - y) // (2 * ay + 1) # 0 if y >= 0, 1 if y < 0
xy = (ax + ay + 1) * (ax + ay) // 2 + ax # encode ax and ay as xy
an = 2 * xy + sx # encode xy and sx as an
n = an - (2 * an + 1) * sy # encode an and sy as n
return n
def decode_pair(n):
""" Inverse of encode_pair. """
# decode an and sy from n
an = (abs(2 * n + 1) - 1) // 2
sy = (an - n) // (2 * an + 1)
# decode xy and sx from an
sx = an % 2
xy = an // 2
# decode ax and ay from xy
ax_plus_ay = (isqrt(8 * xy + 1) - 1) // 2
ax = xy - ax_plus_ay * (ax_plus_ay + 1) // 2
ay = ax_plus_ay - ax
# recover x from ax and sx, and y from ay and sy
x = ax - (1 + 2 * ax) * sx
y = ay - (1 + 2 * ay) * sy
return x, y
And now every integer appears as the encoding of exactly one pair, so we can start with an arbitrary integer, decode it to a pair, and re-encode to recover the same integer:
>>> n = -12345
>>> decode_pair(n)
(67, -44)
>>> encode_pair(67, -44)
-12345
The encode_pair function above is deliberately quite verbose, in order to explain all the steps involved. But the code and the algebra can be simplified: here's exactly the same computation expressed more compactly.
def encode_pair_cryptic(x, y):
""" Encode a pair of integers as a single integer.
This gives a bijective map Z x Z -> Z.
"""
c = abs(2 * x + 1)
d = abs(2 * y + 1)
e = (2 * y + 1) * ((c + d)**2 * c + 2 * (c - d) * c - 4 * x - 2)
return (e - 2 * c * d) // (4 * c * d)
encode_pair_cryptic gives exactly the same results as encode_pair. I'll give one example, and leave the reader to figure out the equivalence.
>>> encode_pair(47, -53)
-9995
>>> encode_pair_cryptic(47, -53)
-9995
I'm no math wiz but found this question kinda fun so I gave it a shot. This is by no means scalable to large number since I'm using prime numbers as exponents and gets out of control really quick. But tested up to 90,000 combinations and found no duplicates.
The code below has a couple extra functions generateValues() and hasDuplicates() that is just there to run and test multiple values coming from the output of myFunction()
BigNumber.config({ EXPONENTIAL_AT: 10 })
// This function is just to generate the array of prime numbers
function getPrimeArray(num) {
const array = [];
let isPrime;
let i = 2;
while (array.length < num + 1) {
for (let j = 2; (isPrime = i === j || i % j !== 0) && j <= i / 2; j++) {}
isPrime && array.push(i);
i++;
}
return array;
}
function myFunction(a, b) {
const primes = getPrimeArray(Math.max(a, b));
// Using the prime array, primes[a]^primes[b]
return BigNumber(primes[a]).pow(primes[b]).toString();
}
function generateValues(upTo) {
const results = [];
for (let i = 1; i < upTo + 1; i++) {
for (let j = 1; j < upTo + 1; j++) {
console.log(`${i},${j}`)
results.push(myFunction(i,j));
}
}
return results.sort();
}
function hasDuplicates(arr) {
return new Set(arr).size !== arr.length;
}
const values = generateValues(50)
console.log(`Checked ${values.length} values; duplicates: ${hasDuplicates(values)}`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/8.0.2/bignumber.min.js"></script>
Explanation of what's going on:
Using the example of myFunction(1,3)
And the array of primes [2, 3, 5, 7]
This would take the 2nd and 4th items, 3 and 7 which would result in 3^7=2187
Using 300 as the max generated 90,000 combinations with no duplicates (However it took quite some time.) I tried using a max of 500 but the fan on my laptop sounded like a jet engine taking off so gave up on it.
If x and y are some fixed size integers (eg 8 bits) then what you want is possible if the return of f has at least as many bits as the sum of the number of bits of x an y (ie 16 in the example) and not otherwise.
In the 8 bit example f(x,y) = (x<<8)+y would do. This is because if g(z) = ((z>>8), z&255) then g(f(x,y)) = (x,y). The impossibility comes from the pigeon hole principle: if we want (in the example) to map the pairs (x,y) (of which there 2^16) 1-1 to some integer type, then we must have at least 2^16 values of this type.
function myfunction(x,y){
x = 1/x;
y = 1/y;
let yLength = ("" + y).length
for(let i = 0; i < yLength; i++){
x*=10;
}
return (x + y)
}
console.log(myfunction(2,12))
console.log(myfunction(21,2))
Based on your question and you comments, I understood the following:
You want to pass 2 real numbers into a function. The function should use mathematical operators to generate a new result.
Your question is, if there is any kind of mathematical equation/function you could use, that would ALWAYS deliver a unique result.
If that's so, then the answer is no. You can make your function as complicated as possible and get a result(c) using the two numbers (a & b).
In this case I would look for another combination which could give me the result(c) using the same equation/function. Therefore I would use the system of linear equation to solve this mathematical issue.
In general, a system with fewer equations than unknowns has infinitely many solutions, but it may have no solution. Such a system is known as an underdetermined system.
In our case we would have one equation which gives us one result and two unknowns, therefore it would have infinitely many solutions because we already have a solution, so there is no way for the system to have no solutions at all.
More about this topic.
Edit:
I just recognized that some of us understood the domain of the function in a different way. I was thinking about real numbers (R) but it seems many assumed you talk about integers (Z) only.
Well I guess
real integers
wasnt clear enough, at least for me.
So if we would use integers only, I have no idea if that is possible to always have different results. Some users suggested a topic about that here I am also interested to take a look into that too.

How Does JavaScript Calculate This Math Expression

Why is the output of this expression 20?
I've tried different calculations but it always leads to the output of 24.
Could some please explain to me how Javascript calculates this expression?
Thank You.
let A = 2;
let B = 4;
let result = B + B * A + 8;
console.log(result);
Output: 20
It follows the rule of PEMDAS (which stands for Parathesis, Exponents, Multiplication and Division, Addition and Subtraction).
What this simply means is that multiplication and division has a "higher" order than addition or subtraction. Which means multiplication and division will take place first before any addition or subtraction.
It's evaluating like this:
result = 4 + 4 * 2 + 8
Because of point before line calculation, a parenthesis is placed around the multiplication.
Like this: 4 + (4 * 2) + 8
Which evaluates to 4 + 8 + 8, and you can't that's 20.
Maybe your calculator didn't do point before line calculation.
Hope I could help.
I hope this helps to understand
let A = 2;
let B = 4;
let result = (B + B) * A + 8;
console.log(result); //Outputs 24
A = 2;
B = 4;
result = B + (B * A) + 8;
console.log(result); //Outputs 20

Why isn't this code working to find the sum of multiples of 3 and 5 below the given number?

I've started with some problems on HackerRank, and am stuck with one of the Project Euler problems available there.
The problem statement says: Find the sum of all the multiples of 3 or 5 below N
I've calculated the sum by finding sum of multiple of 3 + sum of multiples of 5 - sum of multiples of 15 below the number n
function something(n) {
n = n-1;
let a = Math.trunc(n / 3);
let b = Math.trunc(n / 5);
let c = Math.trunc(n / 15);
return (3 * a * (a + 1) + 5 * b * (b + 1) - 15 * c * (c + 1)) / 2;
}
console.log(something(1000)); //change 1000 to any number
With the values of num I've tried, it seems to work perfectly, but with two out of five test cases there, it returns a wrong answer (I can't access the test cases).
My question is what is the problem with my code? as the logic seems to be correct to me at least.
Edit: Link to problem page
Some of the numbers in the input are probably larger than what javascript can handle by default. As stated in the discussion on the hackkerrank-site, you will need an extra library (like: bignumber.js) for that.
The following info and code was posted by a user named john_manuel_men1 on the discussion, where several other people had the same or similar problems like yours
This is how I figured it out in javascript. BigNumber.js seems to store the results as strings. Using the .toNumber() method shifted the result for some reason, so I used .toString() instead.
function main() {
var BigNumber = require('bignumber.js');
var t = new BigNumber(readLine()).toNumber();
var n;
for(var a0 = 0; a0 < t; a0++){
n = new BigNumber(readLine());
answer();
}
function answer() {
const a = n.minus(1).dividedBy(3).floor();
const b = n.minus(1).dividedBy(5).floor();
const c = n.minus(1).dividedBy(15).floor();
const sumThree = a.times(3).times(a.plus(1)).dividedBy(2);
const sumFive = b.times(5).times(b.plus(1)).dividedBy(2);
const sumFifteen = c.times(15).times(c.plus(1)).dividedBy(2);
const sumOfAll = sumThree.plus(sumFive).minus(sumFifteen);
console.log(sumOfAll.toString());
}
}

C# and Javascript code calculations giving different results

I'm doing a Unity project where I have the need to convert UTM coordinates to latitudes and longitudes. I have tried several C# solutions, but none of them were accurate enough. But I found some Javascript code that gives out the exact result I'm looking for (https://www.movable-type.co.uk/scripts/latlong-utm-mgrs.html). The problem is, when I turned the code into C#, it gives out a different result. Here are the pieces of code I see the problem in:
Javascript:
var a = 6378137;
var f = 1/298.257223563;
var e = Math.sqrt(f*(2-f));
var n = f / (2 - f);
var n2 = n*n, n3 = n*n2, n4 = n*n3, n5 = n*n4, n6 = n*n5;
var A = a/(1+n) * (1 + 1/4*n2 + 1/64*n4 + 1/256*n6);
And the C# code I converted myself:
var a = 6378137;
var f = 1 / 298.257223563;
var e = Math.Sqrt(f * (2 - f));
var n = f / (2 - f);
var n2 = n * n;
var n3 = n2 * n;
var n4 = n3 * n;
var n5 = n4 * n;
var n6 = n5 * n;
var A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6);
They should be identical, but the value of A is different. In Javascript it's 6367449.145823415 (what I want), but C# gives 6367444.6571225897487819833001. I could just use the Javascript code in my project, but conveniently Unity stopped supporting Javascript just last year.
The inputs are the same for both functions. What could be the issue here?
You have an issue in the last expression
var A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6);
In C# 1 / 4 * n2 is evaluated to 0 since 1 and 4 are considered as integers by default and integer division 1 / 4 gives 0. Same thing happens to 1 / 64 * n4 and 1 / 256 * n6. But in JavaScript there are only 64-bit floating point numbers, so 1 / 4 is evaluated to 0.25.
Possible workaround:
var A = a / (1 + n) * (1 + 1 / 4.0 * n2 + 1 / 64.0 * n4 + 1 / 256.0 * n6);
Now answers seem to be exactly the same.
Note: as #Lithium mentioned, you may find more elegant to add d rather than .0 to the end of the number to indicate it as double.
This likely has to do with the lack of handling for floating point numbers in javascript. C# handles it fine but not Javascript. If you would like to know more about some of the quirks in Javascript numbers check out the link below.
https://www.w3schools.com/js/js_numbers.asp
In your C# use all your variables as type double. These are twice as accurate as the standard C# floats which I assume it is using by default.
This should give you an identical answer.
Most languages have the concept of a single precision floating point number and a double precision floating point number (32 bit vs 64 bit). Due to JavaScript being a Non-strongly typed language I'm assuming it's picking up the fact that it should use 64 bits for your numbers whereas C# needs to be told that. You should also avoid var in C# wherever possible and use the actual type, to avoid situations like this :p

Javascript formula port from numbers

I am trying to port a formula from numbers (Mac OS 10) to javascript, the original formula is thus:
(1−(1+(C37÷100)÷C39)^−C45)÷((C37÷100)÷C39)
I have written this:
var calcValueOne = (1 - (1 + (yield/100) / coupon_frequency) Math.sqrt() - coupons_until_maturity) / ( (yield/100) / coupon_frequency);
where yield = C37 and coupon_frequency = C39 and coupons_until_maturity = C45
I am getting the following error:
SyntaxError: Unexpected identifier 'Math'. Expected ')' to end a
compound expression.
My mathematics is not to hot and transposing this in to Javascript is proving to be a huge challenge for me, can anyone post a solution to this please?
EDIT
#Musa kindly added a response but the number it is returning is not what I expect so I thought I would expand on the values to see if that helps.
yield (C37) == 9.89
coupon_frequency (C39) == 4.00
coupons_until_maturity (C45) == 15.00
The number I am expecting is 12.41 but I am getting -607.1703544847592 the javascript now looks like this:
var calcValueOne = (1 - Math.sqrt(1 + (yield/100) / coupon_frequency) - coupons_until_maturity) / ( (yield/100) / coupon_frequency);
Again for clarity this is the original (excel / numbers) formula:
The ^ sign is the exponent function not the square root so use Math.pow to calculate it
var yield = 9.89;
var coupon_frequency= 4.00;
var coupons_until_maturity = 15.00
var calcValueOne = (1 - Math.pow((1 + (yield/100) / coupon_frequency), - coupons_until_maturity)) / ( (yield/100) / coupon_frequency);
document.body.innerHTML = calcValueOne;

Categories