Babylonian square root algorithm - initial guess value - javascript

I was looking for Babylonian square root algorithm written in JavaScript, and found this working solution:
function sqrt(num) {
var accuracy = 0.000001;
function isPrecise(estimation) {
if (Math.abs( Math.pow(estimation, 2) - num ) < accuracy) {
return true
} else {
return false
}
}
function improvePrecision(estimation) {
return (estimation + (num / estimation)) / 2;
}
function iteration(estimation) {
if(isPrecise(estimation)) {
return estimation;
} else {
return iteration(improvePrecision(estimation));
}
}
return iteration(num);
}
But I can't see where is initial guess (in code - estimation) value is defined. So how it works, when there is no guess value on first iteration? Actually, this value should be eaqual to num argument.

The estimation is defined inside of the iteration function.
When the function runs the first time, the iteration function is called with the num parameter, return iteration(num).
Inside iteration function, the algorithm first checks if the estimation is ok.
If not, iteration is called again, but this time, it first improves the given estimation
return iteration(improvePrecision(estimation));
So iteration is recursive function, which will call itself unless the estimation is precise enough: (isPrecise(estimation))

Related

Where do I place my return true statement

This is a basic javascript question I just want to better understand. I'm trying to understand if it matters where I place my return true statement. Here's the example code:
function isValid(input) {
for (var i = 0; i < input.length - 2; i++) {
var charOne = input.charAt(i);
var charTwo = input.charAt(i + 1);
var charThree = input.charAt(i + 2);
if (charOne === charTwo && charOne === charThree) {
return false;
}
return true;
}
}
isValid("ABB");
This returns true, but also returns true if I place the return true statement here:
function isValid(input) {
for (var i = 0; i < input.length - 2; i++) {
var charOne = input.charAt(i);
var charTwo = input.charAt(i + 1);
var charThree = input.charAt(i + 2);
if (charOne === charTwo && charOne === charThree) {
return false;
}
}
return true; // Moved this return statement
}
isValid("ABB");
Is one way wrong and the other correct?
Your first version, you are returning true within the for loop. That means its only going to execute your loop once and then return. That's likely a bug.
Your second version is likely correct. The return true statement executes from the function after the for-loop completes all iterations from [i..length-2).
second one, since in the first one after each iteration , you check if characters are equal and it will return false or return true in the first iteration itself.In, second one you check for all combinations and if it's never false then it must be true.
When you return inside a for loop you finish the whole loop and carry on outside it.
So the answer is it depends, if you want to miss out an item and carry on looping after the return statement then doing a return isn't what you want.
The return you put outside of the loop allows the loop to complete before returning the result.
Note a useful keyword you can use inside a loop if you want to finish the iteration rather than breaking the whole loop is continue.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue
I don't think one is wrong necessarily. I actually prefer a slightly different approach.
For clarity I generally will do something like this. So it is clearly one or the other.
With a return it is obvious that calculations within the function stop at that point. I just like it to look obvious.
if(charOne === charTwo && charOne === charThree) {
return false;
} {
return true;
}

What is the logic behind this double function call with recursion?

Where I currently have the console logs, countdown seems to count down from 10 to 1 (this makes sense) but then after this, way seems to add 15 to the final result of countdown 9 times, but for this to happen, I'd imagine that after each countdown loop, way is called, but that each keeps track of its own value? Any clarification about the Why and When of this logic would be helpful - Thanks!
var countdown = function(value) {
value = value - 1;
if (value == 0) {
return value;
}
console.log("loop 1 " + value);
return way(countdown(value));
};
function way(value) {
value = value + 15;
console.log(value);
return value;
}
countdown(10);
As commented above value is a local variable in either function and thus always bound to the scope of either function. It doesn't actually contribute to confusion aside from expecting too much complexity there. ;)
The behaviour arises from countdown() being called recursively and calling way() has to wait until recursive calls for countdown() are returning. But that's not happening until countdown()'s recursion has stopped at value 0 to be returned eventually. After that countdown() isn't invoked ever again, but since countdown() was invoked recursively and this is bubbling up through all invocations of countdown() there are multiple calls for way() with the result returned from the countdown() called at end which in turn was calling way() with result of countdown() etc. ... ok, got a bit confused here myself.
Since value isn't required to be that complex it might help to eliminate it for reducing code:
function countdown(value) {
if ( value == 1 ) { return 0; } // bail out condition
console.log("loop 1 " + value)
return way( countdown( value - 1 ) );
};
function way( value ) {
console.log(value);
return value + 15;
}
countdown(10);
way() is of no relevance to the recursion and thus might be substituted:
function countdown(value) {
if ( value == 1 ) { return 0; } // bail out condition
console.log("loop 1 " + value)
return countdown( value - 1 ) + 15;
};
countdown(10);
Due to recursion this code is diving into stack 9 frames deep. And then it is bubbling up stack returning the result of every passed frame increased by another 15 prior to bubbling up further on.
So actually, there is only one recursion.
At first, the code starts executing your first call to countdown with argument value=10
Stack: []
Execute countdown(10)
Stack: [countdown(10)]
Then execute way(countdown(9)), and to execute this, JS first evaluates countdown(9)
Stack: [countdown(10), countdown(9), ] and so on, you can imagine, until you reach countdown(0), then start popping out from the stack call.
First stack call resolved, countdown(0) = 0, then call way(0), the console logs 0+15, then countdown(0) eventually returns 15, then pop from stack countdown(1) which is equal to way(countdown(0)), which is way(15), then prints out 30, and so on...
Hope this is clear enough
In order to understand this recursive code, it's easiest to follow the program counter:
function way (value) {
value=value +15
console.log(value)
return value
}
countdown = function(value) {
value = value-1
if (value == 0) {
return value;
}
console.log("loop 1 " + value)
return way(
countdown(value));
};
countdown(10);
Start countdown with 10
value > 0 so run way(countdown(9)) //note: countdown is executed first.
Countdown runs with 9
value > 0 so run way(countdown(8)) //note: countdown is executed first.
...
...
...
value == 0, return 0 (in countdown): execute way
way returns 0 + 15
way returns 15 + 15
way .... etc.
As fora clarification why this logic would be helpful; I think there is a lesson to be learned here.
Basically there are 2 relevant function-call positions when applying recursion:
positioned before recursive call
positioned after recursive call
I will leave it as an exercise of why this has any relevance.

How i put together two functions, both with a recursion inside

I am a beginner and this my first post here(plus I'm not a native English speaker), so please forgive me if my code and/or my English are bad.Given two numbers I want to write a JavaScript function to find if the second one is a power of the first one, and then determine that power (ex: 2,8 the output must be 3). I wrote two functions, both working, but I can't put them together.
This is the first one to check if the second number is a power of the first one.
function checkNumbers(x,y){
if (y%x !==0){
return "this numbers are not valid"
}
else if(x===y) {
return "correct!"
}
else {
y=y/x
return checkNumbers(x,y)
}
}
checkNumbers(2,8) // will give the first answer
checkNumbers(2,18) // will give the second answer
The second function will give you the integral logarithm:
count =1;
function findGrade(x,y) {
if(y/x===1)
return "the grade is " + count;
count++;
y = y/x;
return findGrade(x,y)
}
findGrade(2,8) // output 3
findGrade(2,16) // output 4
How can I put them together into one function? I think i need a closure, but I didn't find the way to make that work.
checkNumbers should return a Boolean value, not a message. Then findGrade can check that result to see whether it should compute the logarithm. Something like this:
function checkNumbers(x,y){
if (y%x !==0){
return false
}
else if(x===y) {
return true
}
// the rest of your function remains the same.
function findGrade(x,y) {
// First, check to see whether y is a power of x
if checkNumbers(x,y) {
// your original findGrade function goes here
}
else
return -1; // Use this as a failure code.
Does this work for you?
Another possibility is to combine the functions entirely: try to find the logarithm (what you call "grade"); if it works, you get your answer; if it fails (at y%x !== 0), then you report the failure.
The solution is, in fact, pretty simple.
You could do the following:
function findGrade(x, y, count = 1) {
// If the numbers are not valid, throw an error. The execution is interrupted.
if(y % x != 0) throw "Invalid inputs";
// If the inputs are different, continue the execution and add 1 to count.
if(x != y) return findGrade(x, y/x, ++count);
// If none of the above are true, you have your result!
return count;
}
Tests:
console.log(findGrade(2, 8)); // Outputs 3
console.log(findGrade(2, 16)); // Outputs 4
console.log(findGrade(2, 3)); // Error: Invalid inputs
console.log(findGrade(3, 3486784401)); // Outputs 20
Please let me know if you need any further help.
I'm not sure if my method is different, but I have implemented it below. In real world application I would do some more typechecking on inputs and check if there is a third argument: if not default to 0 (First Iteration default the count to 0), but this is the general idea. You can run the snippet below.
// Arguments
// 1: Base of Exponent
// 2: test Number
// 3: count by reference
function checkPower (base, test, count) {
let division = test/base
// base case
if (division === 1) {
count++
return count
} else if (division < 1) {
console.log("not a power")
return;
}
// iteration step
count++
return checkPower(base, division, count++)
}
// Test Cases
let test = checkPower(2, 32, 0)
if (test) {
console.log(test) // 5
}
test = checkPower(2, 1024, 0)
if (test) {
console.log(test) // 10
}
test = checkPower(2, 9, 0)
if (test) {
console.log(test) // "not a power"
}

Javascript: For Loop, need help understanding this exercise with if/else

I have this exercise that already got the answer, but after hearing the explanations, still don't understand. This is the exercise:
"write a function isUniform() which takes an array as an argument and
returns true if all elements in the array are identical"
This is the solution
function isUniform(numArr) {
var first = numArr[0];
for (var i = 1; i < numArr.length; i++) {
if (numArr[i] !== first) {
return false;
}
}
return true;
}
I got it almost right, but i did a else statement with the "return true" and it didn't work. Why does it work with the "return true" outside of the for loop?
(edited) This is how i did the first time:
function isUniform(numArr) {
var first = numArr[0];
for (var i = 1; i < numArr.length; i++) {
if (numArr[i] !== first) {
return false;
}
else {
return true;
}
}
}
If you return true outside the loop, then it checks every element in the loop until one matches the if test or it gets to the end of the loop.
If you return true inside the loop then it will always hit a return statement for the first element and then stop the loop.
I got it almost right, but i did a else statement with the "return
true" and it didn't work
The solution below would return the wrong results in some cases because all it does is find the first element within the array that's equal to first variable and return true, even though it hasn't searched the entire array.
function isUniform(numArr) {
var first = numArr[0];
for (var i = 1; i < numArr.length; i++) {
if (numArr[i] !== first) {
return false;
}
else {
return true;
}
}
}
I have this exercise that already got the answer, but after hearing
the explanations, still don't understand.
let's assume this is your array:
[10,10,13,10,10]
let's assume this is the variable first:
first = 10;
The if statement below which is within the for loop basically says if the variable first ( 10 ) is not equal to the element at the current index i (nth number within the array) then return false. This makes sense because if at this moment the variable first is not the same with the element at the specified index for example index 2 (number 13) then there is no point to carry on. Hence, it will return false.
if (numArr[i] !== first) {
return false;
}
now let's assume the array is:
[10,10,10,10,10]
let's assume this is the variable first:
first = 10;
now the variable first will be compared against each elementwithin the array and it says "is 10 not equal to the current element". in this case that's false because 10 is equal to 10. This will propagate down the array and control will never pass inside the if block. Eventually, control passes down to the return true statement.
if (numArr[i] !== first) {
return false;
}
It works because is the final statement in your function. Basically your function will return true if the condition inside for loop will not be triggered
Let's say you've got a broken printer which once in a while messes the printout. Now you printed 20 copies and want to know if every paper is fine. So now you would have to iteratively compare every copy until you found one which is not matching (and know it's time to get a new printer?). Or you've gone the way through the hole stack and know every copy is fine (and you've wasted time for nothing).

Newb: Why does this variable persist instead of getting reset?

I suppose this is a newbie question, but I can't seem to figure it out. I have this code, from eloquent javascript, about the reduce function:
function forEach ( info, func ) {
for ( i = 0; i < info.length; i++) {
func(info[i]);
}
}
function reduce (combine, base, array) {
forEach(array, function(elem) {
base = combine(base, elem);
console.log("The base is: " + base);
});
return base;
}
function countZeroes(array) {
function counter(total, element) {
console.log("The total is: " + total);
return total + (element === 0 ? 1 : 0);
}
return reduce(counter, 0, array);
}
What I can not figure out is, how is the number of zeroes stored in total through each call of the function? Why does it keep a running tab, instead of getting wiped out each time?
The structure of reduce is that it applies a function f which takes two operands - here called element and total to a sequence. element is the next unprocessed item in the sequence (array); total is the result of the previous call to f.
Conceptually reduce(f, 0, [1,2,3]) expands to f(3,f(2,f(1,0).
Now, to answer your question: the running total is stored between invocations of counter in the variable base inside reduce.

Categories