Great common divisor with loops - javascript

I think my logic is wrong but I can't understand where I am making a mistake. I am trying to find the great common divisor, and code will determine what to do if a is bigger than b or b is bigger than a.
I tried many loops, if, while but in the end I deleted all to clear my sight. I made flowchart however it is not coming along with my code.
var a = 64;
var b = 12;
var newA;
while(a > b && newA != 0){
newA = a - b;
if(newA === 0){
outputObj.innerHTML = outputObj.innerHTML + "GCD is " + b;
}
}
while(a < b && newA != 0){
newA = b - a;
}
if(newA === 0){
outputObj.innerHTML = outputObj.innerHTML + "GCD is " + a;
}
}
If a is 64 and b is 12 the GCD is 4, if a is 35 and b is 42 the GCD is 7

You have a few different problems here. This looks like homework, so I'll try to point you in the right direction for a couple of the problems rather than e.g. telling you exactly what your code should say.
In your loops, you never update the value of either a or b.
Pretending that that's fixed, your code will either subtract a from b several times or subtract b from a lots of times. Doing that computes the remainder on dividing one number by the other, not the greatest common divisor.
I'm betting that you've been given a description of an algorithm for computing the greatest common divisor. Read through it again, comparing what it does against what your code does.
Here's a powerful method for finding problems in this sort of code: try to run it in your head, pretending that you're the computer. Go through, step by step, doing what the computer will do. With your code above, it might begin like this:
OK, I've got variables called a and b, whose values are 64 and 12. And a variable called newA, whose value hasn't been specified yet.
Now I need to check whether a is bigger than b -- yup, it is -- and then whether newA is zero.
Wait, I haven't given newA a value at this point. (You've found a bug here. Let's pretend it's fixed and move on.)
Now I set newA to be a-b, which is 52.
Now I check whether newA is zero, which it isn't so I don't need to do the stuff inside the if block there.
OK, so we've done one iteration of the while loop. Back to the start of the loop.
Now I need to check whether a is bigger than b -- yup, it is -- and then whether newA is zero.
Wait a minute, I'm checking the exact same thing as last time: nothing's changed. How's this loop going to end? (You've found another bug here.)
And so on.

Related

Merge two sorted arrays (leetcode 88): i cant understand how it wont go out of bounds

The solution I came across using two pointers:
var merge = function (nums1, m, nums2, n) {
let idx1 = m - 1,
idx2 = n - 1,
idx3 = m + n - 1;
while (idx2 >= 0) {
nums1[idx3--] = nums1[idx1] > nums2[idx2] ? nums1[idx1--] : nums2[idx2--];
}
};
The solution works but I can't understand this,
Consider nums1 = [7,9,11,0,0,0,0], nums2 = [1,2,12,14],
at a point in the algorithm, the index for nums1 is at 7 and at 2 on nums2,
the next iteration will lead idx1 too be -1, what will happen at the comparison statement from then on?
(I hope I was able to make the question clear, please let me know if I need to put it in better words)
This code can go out of bounds in 2 places, but it works fine, because Javascript is a little weird when it comes to out-of-bounds array accesses:
It can write new elements past the end of nums1. Javascript will automatically lengthen the array to accommodate the new value.
It can compare nums1[-1] > nums2[idx2]. nums1[-1] is undefined, so this comparison will always be false, which is exactly what the author wants.
If you ever write code like this, you should add comments explaining why it works, since it relies on peculiarities of Javascript that do not carry over into other languages and won't be obvious to everyone reading the code.

xor: N things with variable probabilities

Forgive me; I'm a coder and not a mathematician, so I'm asking this to my own stack. I'm trying to reduce an array of probabilities (0-1), let's say [.1,.3,.5] to find:
The likelihood of all of them happening (simple multiplication, let's call this function AND: probs.reduce((m,p)=>p*m,1)),
1.1 This can be written
any one of them happening (one minus none of them happening 1 - probs.reduce((m,p)=>m*(1-p),1), call it OR), and
2.1 This can be written
XOR ONLY one, no more and no less, of them happening. At first I thought this was simple because if there are only two inputs, the chance of only one happening should be OR minus AND. But as I'm banging my head on this as an array of more than two values, normal XOR logic seems to disintegrate.
3.1 This can be written (verbosely)
Do I need to get the "OR" and then subtractively multiply all possible AND scenarios iteratively? Or is there a non-iterative formula to find out the total probability of exactly one probability in a list longer than two?
0,0,0 should be 0 in my case. 0,.4.0 should yield a .4 of only one happening. 1,.4,0 should yield 0.6. I know that .5,.5 should yield 0.25 chance of only one happening. But I'm really not sure how to calculate the chance of only one .5,.5,.5 without counting on my fingers. My mind is saying I have to loop through each probability, and subtract from it the chance of any others (OR the rest of the array), then OR the final results... but this is speculative. That seems very weird and inefficient. I can't believe this would be an NP-Hard problem, but it's a corner of things I'm not familiar with...
Please answer in visual, logical or programmatic terms, not pure Math if possible...
** Edit here: I don't need to clarify the exact probability of a particular element in the array being exclusive to the others; I'm trying to find the general probability of any of them being exclusive. **
** Edit. This is what I've got now. I'm excluding all other possibilities for each individual one. Is this the fastest way?... *
function And(probs) {
return (probs.reduce((m,p)=>p*m,1));
}
function Or(probs) {
return (1 - probs.reduce((m,p)=>m*(1-p),1));
}
function Xor(probs) {
let _exclusiveProbabilities = [];
for (let k=0; k < probs.length; k++) {
let _others = [];
for (let j = 0; j < probs.length; j++) {
if (j != k) {
_others.push(probs[j]);
console.log(k,'pushed',probs[j]);
}
}
const _anyOtherProb = Or(_others);
_exclusiveProbabilities.push(probs[k] * (1 - _anyOtherProb));
}
return (Or(_exclusiveProbabilities));
}
** edit. Nope, that's great for two but doesn't work for three. **
Let's say you have three probabilities, which we'll call A, B, and C.
The probability of A being the only event that happened is A * (1-B) * (1-C). In other words, in this scenario A happened, but B did not happen and C did not happen.
But, of course it is possible that B was the only successful event, or that C was the successful event. We will need to sum together the probabilities of all of these situations.
So, we are going to need to loop through all of the events, and compute the probability that only that event happened (and all the others failed), and then compute the sum.
For the case of three events, this would be:
( A * (1-B) * (1-C) ) + ( (1-A) * B * (1-C) ) + ( (1-A) * (1-B) * C )
If there are N total events, then there will be a total of N^2 (N squared) total terms in this expression.

Comparing big numbers in Javascript

I've got two numbers that I want to compare. The numbers in the following example are the result of 26^26 computed in two different systems. One of which is my javascript code.
However, when comparing the two numbers I end up with something like this:
AssertionError [ERR_ASSERTION]: 4.0329146112660565e+26 == 4.0329146112661e+26
They're obviously not equal, but theoretically they should.
What's the proper way to perform equality on big numbers in javascript (even if it's an approximation)?
If what you're trying to do is determine if two numbers are practically equivalent you'll have to come up with your margin of error. One way to do this is to compute the difference between the numbers and then determine if that difference is significant or not.
So, taking your numbers from before, we could evaluate the difference between these numbers through subtraction. Since we don't really care about the sign of this difference, I'll go ahead and get the absolute value of the difference.
Math.abs(4.0329146112660565e+26 - 4.0329146112661e+26) === 4329327034368
(Sidenote: Now is not the time to explain why, but the == operator in JavaScript has confusing and error-prone behavior, use === when you want to compare values.)
That difference is a HUGE number, but related to how big our numbers are in the first place, it's rather insignificant. Intuitively, I'm tempted to divide the difference by the smallest of our original numbers like so:
4329327034368 / 4.0329146112660565e+26 === 1.0734983136696987e-14
That looks like a pretty small number. Repeat that same operation with a bunch of values and you should be able to determine what you want your margin of error to be. Then, all you'll have to do is perform the same operations with arbitrary numbers and see if that "difference ratio" is small enough for you.
function similar(a, b) {
let diff = Math.abs(a - b);
let smallest = Math.min(Math.abs(a), Math.abs(b));
let ratio = diff / smallest;
return ratio < MARGIN_OF_ERROR;
}
Now I just came up with that way of determining the importance of the difference between two numbers. It might not be a very smart way to compute it, it might be appropriate to some situations and not to others. But the general idea is that you'll have to make a function that determines if two values are close enough with your own definition of "close".
Be aware though, JavaScript is one of the worst languages you can be doing math in. Integers become imprecise when they go beyond Number.MAX_SAFE_INT (which seems to be 9007199254740991 according to Chrome, not sure if it varies between browsers or if that's a standardized constant).
Update: If your target engine is es2020 or above, you can use the new BigInt javascript primitive, for numbers higher than Number.MAX_SAFE_INTEGER
BigInt(4.0329146112660565e+26) === BigInt(4.0329146112661e+26)
//false
See more information in MDN
var a = 4.0329146112660565e+26;
var b = 4.0329146112661e+26;
a = Math.round(a/10e+20)*10e+20
b = Math.round(b/10e+20)*10e+20
a == b;
I would suggest to use one of big numbers library:
big.js (https://www.npmjs.com/package/big.js)
Example:
var x = new Big('4.0329146112660565e+26');
var y = new Big('4.0329146112661e+26');
// Should print false
console.log('Comparision result' + x.eq(y));
big-numbers (https://www.npmjs.com/package/big-numbers)
Example:
var x = bn.of('4.0329146112660565e+26');
var y = bn.of('4.0329146112661e+26');
// Should print false
console.log('Comparision result' + x.equals(y));

Is it possible to convert A string that is an equation with a variable into a equation?

I need to convert a string returned from prompt into an equation, however the parseFloat returns as only the first number, and symbols in an equation, and stops at the variable. The variable will always = x. The program is designed to convert an algebraic expression say 15*x(5^4-56)*17/x=15 into an expression, and calculate the value of x. If someone could show me how to do this, it would help dramatically. I am currently using multiple prompts, having the user put in the equation before x, then the equation after x, then it inserts a variable in between the two, and calculates it's value.
Edit:
I have no variables predefined, and it must work in equations where x > 1000, or x != //an integer.
Thanks in advance!
Seems to be a complex problem...
This is a solution for a simple relaxed version of your problem. Hope you can use some components of this.
Constraints:
answer for x should be integers between 0 and 1000
the left hand side of the expression should be proper javascript syntax
var input = prompt("enter the equation"); //eg: x*x+x+1=241
var parts = input.split('=');
//solving equation starts
var x = 0;
var temp = eval(parts[0]);
while (temp != parts[1] && x<1000){
x++;
temp = eval(parts[0]);
}
var ans = (x<1000)?"answer is "+x:"this program cannot solve this";
//solving equation finishes
alert(ans);
You can replace the "solving equation" part with some numerical methods used in computer science to solve equations (more details here) . You will have to parse the left side of equation and map them to proper javascript expressions (as a string to execute with eval()) if you want to allow users to use your syntax.
Javascript can evaluate strings using the eval function, but the variable as to be defined before hand, and the equation has to be formatted in way that javascript can understand:
var x = 15
var string = "15*x*17/x"
eval(string)
Your example: "15*x(5^4-56)*17/x=15" would not run however, because it would evaluate x(5^4-56) as a javascript expression, which is invalid.
Using all the info, and other mehtods I found about this, I have put together a communinty answer. Anyone is invited to change and/or add their methods to this.
In order to do this with the least work possible for the user and coder, you would implement the following code.
var input = prompt("enter the equation"); //eg: x*x+x+1=241
var parts = input.split('=');
//solving equation starts
var x = 0; //Or the lowest possible value of "x"
var temp = eval(parts[0]);
while (temp != parts[1] && x<1000){ // && x < The highest number to evaluate
x++; //Add the increment (determines the maximum amount of digits) eg x+0.1 for tenths max, x+2 for only even integers etc.
temp = eval(parts[0]);
}
var ans = (x<1000)?"answer is "+x:"this program cannot solve this"; //make sure x< is the same as line 7.
//solving equation finishes
alert(ans);
But, this runs very slowly if you allow tenths, or a range larger than 2000.`
A faster way of running this would be to define arrays allowing any variable (instead of just x) and a different eveulation process such as here. (do the right click view html and click on the first js source to see code) but, this is 2k lines. Both are usable, but the second is more efficient, and can solve multivariate equations.

Same periodic number is different for a if

I'm building a javascript-based web-app;
With a particular data input, a function returns a value of 10/3 = 3.333333333333333 (this is the amound of decimals shown by a colsole.log call); After about 200 lines of code, I have 2 variables (A and B) that contains that value, and I need to check if it is the same value;
The fact is, how is it possible to have an output like this?
console.log(A); //3.333333333333333
console.log(B); //3.333333333333333
console.log(A == B) //false
console.log(A-B == 0) //true??
I can imagine A == B is false due to how numbers are saved in the memory, but I wish it was a true; and what is really unexplainable to me is how comes the last line output is true?
console.log (or even toString) won't show you the full number down to the bit-by-bit difference. The floating point numbers used in JavaScript (and many other languages) are IEEE-754 double-precision floating point, and they're not perfectly precise, small discrepancies appear and can multiply.
Now, if you literally created A and B like this:
var A = 10 / 3;
var B = 10 / 3;
...then both comparisons would be true (proof). So apparently you're getting A one way, and B another, and the fact is that they are ever-so-slightly-different. (I'm quite surprised to hear A == B says false but A - B == 0 says true, though.)
You'll need to round them to the number of digits you think is appropriate, and compare the rounded result.

Categories

Resources