beginner here. Was working through a code question on fcc and came across some javascript code I can't seem to understand.
function sum(arr, n) {
// Only change code below this line
if (n <= 0) {
return 0;
} else {
return sum(arr, n - 1) + arr[n - 1]
}
// Only change code above this line
}
console.log(sum([2, 3, 4, 5], 3))
// Console then spits out "9"
I understand how the second have of the return statement "arr[n - 1]" produces
4", but I'm unsure of how the first half "sum(arr, n - 1)" comes up with the number "5" that when added to 4, gives me the number "9" in the console.
I've narrowed it down to "sum(arr, 2)", but I can't seem to understand what the code is doing?
Thank you in advance!
sum(arr,2) calls the same function "sum" with the same arr parameter and a limit that's 2 instead of 3.
While the first call (inside console.log) is supposed to add a number of parameters (3), the second call (inside the first) should add all parameters but the last one (2), which is added explicitely.
That's the point of recursion: a function that calls itself until a specific condition is met. The condition in this case is if there is no element left to be added (n<=0). Up to this all numbers appear as "arr[n-1]" in the chain of calls and are added to 0 (which is the return value in the case of the ending condition). So the actual sum is calculated as all recursive calls return one after the other.
Related
I've been trying to see what's happening exactly with this code by stepping through it in Google Chrome. How and when does the sort method move each element in this array?
I cannot figure out why "b" is index 0 and why "a" is index 1 initially. Logically a should be 10.99 and "b" should be 5.99.
And where is the data getting temporarily stored as it moves through the elements in the array?
Also, when are the elements "shifting"?. Meaning what is happening through each time the a,b parameters move to compare the next a,b set of numbers of the prices array in this sort() function?
const prices = [10.99, 5.99, 3.99, 6.59, 8.49, 1.99, 12.99];
const sortedPrices = prices.sort((a, b) => {
if (a > b) {
console.log("a is greater than b. a moves right, b moves left.");
return 1;
} else if (a === b) {
console.log("a is the same value as b.");
return 0;
} else {
console.log("a is less than b. a moves left, b moves right.");
return -1;
}
});
console.log(sortedPrices);
This image is the sorting order as I followed what numbers were compared to each other. The beginning of the arrow represents "a" and the end of the arrow with the "<" represents "b". Where it gets confusing on top of trying to understand the above issue, is why when the sort method gets to 1.99, why does it skip 8.49 and get compared to 6.59?
partially it is explained there: Javascript Array.sort implementation?
initial values are different for different implementations in different engines
look at the native code of this method, which are provided there: Javascript native sort method code
also I recommend read more about sorting algorithms
I started learning website development (just over 2 months now), learning frontend with HTML, CSS and JS. I am currently on the Eloquent JavaScript book. I did the "sum of range" exercise in chapter 4 of the book, I was able to code the range function, got a little help on the sum function, and competed the exercise. What I want now is to know how well written my solution is, and if there is a better way. This is the exercise and my code solution follows:
Write a range function that takes two arguments, start and end, and returns an array containing all the numbers from start up to (and including) end.
Next write a sum function that takes an array of numbers and returns the sum of these numbers.
As a bonus assignment, modify your range function to take an optional third argument that indicates the "step" value used when building the array. If no step is given, the elements go up by increments of one, corresponding to the old behaviour. The function call range(1, 10, 2) should return [1, 3, 5, 7, 9]. Make sure it also works with negative step values so that range(5, 2, -1) returns [5, 4, 3, 2].
My solution:
function range(start, end, skip) {
let arr = [];
let count;
for (count = start;start < end ? count<=end : count >= end ; count+= skip) {
arr.push(count);
}
return arr;
}
function sum(numbers) {
result = 0;
for (let num of numbers) {
result += num;
}
return result;
}
All I need now is a somewhat "code inspection". Thanks in advance!
I'm studing an algorithm problem and I did understand all the things except the lines that I marked up with comment into the code.
Note: It is not to solve the code. The code is working good. It is only to explain me about what is the marked lines' purposes.
let arr= [40, 50, 80, 20, 21, 35]
function qSort(arr) {
if(arr.length == 0){ // <-- These lines. I did NOT understand its purpose
return [];
}
var left = []
var right = []
var pivot = arr[0]
for(var i= 1; i<arr.length; i++) {
if(arr[i] < pivot) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return qSort(left).concat(pivot, qSort(right))
}
console.log(qSort(arr))
This code is working good, but When I comment these lines into the code, the script doesn't work and it cause an error message referencing a loop issue: Uncaught RangeError: Maximum call stack size exceeded
Does anybody explain it to me please? I would like to know what is this lines' purpose. Thanks
If the given array has a length of 0 (is empty), just return an empty array, because there is no sorting to be done.
Actually the line could be:
if(arr.length <= 1){
return arr;
}
since for 0 and 1 elements the's no sorting to be done.
This is related to the function being recursive (it calls itself) and therefor it needs a case, at wich it stops calling itself and return a value. That's called a recursion anchor.
This is called the base case of recursion, which ends the recursion. If you leave it away, qSort will call qSort will call qSort will call...
This line was written for optimization.
If there is no data in array you have nothing to sort.
Plus when you sort elements you are passing smaller and smaller chunks of base array to qSort function, so you have to finish qSort execution at one point.
So basically it tells the code "There is nothing to sort".
The problem is very simple, I have a function from 'Javascript Allonge' book, and having a hard time in understanding it.
The function is called even, and it's as follows:
var even = function(num) {
return (num === 0) || !(even(num -1));
}
it checks whether the number is even or not, but I do not understand how. It calls itself recursively, and technically, always reaches zero, no? How does that work?
This is based on an inductive definition of numbers being odd or even - a number, n is 'even' when the number before it, n - 1 is odd. This thinking naturally makes sense - 4 is even if 3 is odd.
And so the function even is defined as:
1. even(0) is true - because 0 is even
2. even(n) is the negation of even(n - 1)
Another way to think of it is imagine even(4) being called step by step. By hand, replace the even(4) with result of evaluation it with your function:
even(4)
= !(even(3))
= !(!even(2))
= !(!(!even(1))
= !(!(!(!even(0)))
= !(!(!(!true))
= true
// ...even(4) == true
Well, divide and conquer.
First of all you have two expressions to calculate. The first one is just stopping the recursion at the point when the number is 0, this is easy.
The second expression
!(even(num -1))
is a bit more complicated. It always starts with a call even(num -1) and then negates it.
For the first element !(even(num -1) === true), so now you see that for every second element starting from 1 (1, 3, 5 etc.) it will return false, for others the inverted value.
But there is a negation on the recursive call to even, so that, for every activation record on the stack, the return value gets inverted:
0 --> true
1 --> true --> false
2 --> true --> false --> true
This function indeed calls itself recursively, but with an added inversion each time. return (num === 0) returns true when num equals zero. If num is greater than zero, it calculates the result of even(num-1) and inverses it.
So, with num = 1, the function returns the inverse of even(0), which is true, making the end result false. With num = 2, the function returns the inverse of even(1), which we've just shown to be false, making the end result true. The same principle applies for all integers.
So basically i just started learning JS and had a little exercise which was basically making a function to check if the number is even without using modular arithmetic. When i was done with it i just wanted to compare mine with the answer and i couldn't really get how does it work.
function isEven(n) {
if (n == 0)
return true;
else if (n == 1)
return false;
else if (n < 0)
return isEven(-n);
else
return isEven(n - 2);
}
I'm not sure how the part (n-2) works does it somehow puts the number in a loop and basically does n-=2 until the number gets 1 or 0?
Let's take a look at what is going on behind the scenes when this function is run:
isEven(8)
// isEven(8) Is 8 even?
// isEven(6) Is 6 even?
// isEven(4) Is 4 even?
// isEven(2) Is 2 even?
// isEven(0) Is 0 even? --> Yes, the function immediately returns true
// so I know the one at the top, 8, is even
And so on. For any even number, it eventually gets to 0. For any odd number it eventually gets to 1.
If the number is negative, the function makes it positive and runs itself again against the positive value, if it's > 1, it will run itself again until the number is 1 or 0, decreasing the number by 2 on each iteration. It's called recursion.
When n <0 it puts a minus before the n in the function and runs it again. If Else then the function is called again but n is decreased by 2. This runs till you get true or false.