An interview question,
What's computed by this code?
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(10);
a) 10!
b) Nothing, it's an infinite loop.
c) 10 to the power of 10
d) 10!/10
e) The 10th Fibonacci number.
a) 10! meaning the factorial of 10 (mathematical expression for 10 x 9 x 8 x ... x 1)
You can have a guess of the result with the successive calls:
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(1);
1
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(2);
2
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(3);
6
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(4);
24
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(5);
120
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(10);
3628800
Then if you analyse the code :
the function returns 1 if the input is 0.
if the input is greater than 0 it returns the input multiplied the function called with n-1.
More precisely, (n && n*arguments.callee(n-1)) is a boolean operation and it's return value is the last operand evaluated to true, which is the value of n*arguments.callee(n-1) each time n>0, and 1 instead (thanks to ||1).
arguments.callee is a recursive call in javascript.
A simple way to analyze recursive calls is to write down a stack of all calls and then evaluate in popping order.
[
10 * (recurse with 10 - 1),
9 * (recurse with 9 - 1),
8 * (recurse with 8 - 1),
7 * (recurse with 7 - 1),
6 * (recurse with 6 - 1),
5 * (recurse with 5 - 1),
4 * (recurse with 4 - 1),
3 * (recurse with 3 - 1),
2 * (recurse with 2 - 1),
1 * (recurse with 1 - 1),
1 (recursion stops because 0 is falsey, therefore 1 will be returned)
]
Then we take the stack and evaluate our way up:
[
10 * 362880 = 3628800,
...,
6 * 120 = 720,
5 * 24 = 120,
4 * 6 = 24,
3 * 2 = 6,
2 * 1 = 2,
1 * 1 = 1
1 = 1 <-- start here then work up
]
From this, we can clearly see that the algorithm is a) 10!.
Related
please someone explain this to me
function func(x, n) {
if (n == 1) {
return x;
} else {
return x * func(x, n - 1);
}
}
console.log(func(2, 4)); // 16
how do answer is 16
I could not understand more than this
when if is false it going to else
in the return section function call itself
at the first input is the same value as x, ie 2
at the second input is n - 1
when function run again the value of x remains the same as 2 and the value of n becomes 3
that's mean 3 times if is false
in the 4 times if if true and the execution loop ends and show answer in alert
i can not figure out what number is multiplied by x per run or the answer should be the same as 2
because every time the function is executed, shouldn't the value of x be equal to 2?
If you are asking about how recursion works, then I will explain you with this basic flowchart diagram.
I also edited your JS Code so it will provide you with clarification.
function func(x, n) {
if (n == 1) {
return x;
} else {
let function_returned = func(x, n - 1);
console.log(x, "*", function_returned, "=", x*function_returned)
return x * function_returned
}
}
console.log(func(2, 4));
The function performs exponentiation. So func(x, n) is calculating xn.
It uses recursion, based on the following principle:
When n is 1, then xn = x1 = x
When n > 1, then xn = x.xn-1
For the second statement we can use the function with arguments x and n-1.
For the concrete example, func(2, 4), this is what happens:
x=2, n=4, so we get in the else block and evaluate:
2 * func(2, 3)
For this nested call of func we have x=2, n=3, and again we get in the else block for that:
2 * func(2, 2)
And again we have a nested call, which evaluates to:
2 * func(2, 1)
...and this final nested call gets into the if block and evaluates to:
2
Now we need to backtrack as each nested function call returns the result to its caller:
2 is returned for func(2, 1) which turns 2 * func(2, 1) to 4
That 4 is returned for func(2, 2) which turns 2 * func(2, 2) to 8
That 8 is returned for func(2, 3) which turns 2 * func(2, 4) to 16
And that 16 is what you get in the output
It's a recursive power function. What it does is the following:
2^4 = ?
2 * 2^3 = ?
2 * 2 * 2^2 = ?
2 * 2 * 2 * (2^1) = ? // at this point we get to n == 1 and this is where result is just x which is 2 in your example. From this point we can start moving "back"
2 * 2 * (2 * 2) = ?
2 * (2 * 4) = ?
(2 * 8) = ?
16 = ? // 16 is just 16, we're done.
Your can read a bit about recursion to get a better idea on what is going on.
I looked at https://math.stackexchange.com/questions/519845/modulo-of-a-negative-number and Modulo operation with negative numbers but I still wonder how to use a negative modulo value to get items in a range.
Here is a simplified use case before my question bellow, I have a slideshow with 3 slides (slidesCount = 3):
slide indexes: 0 1 2
Now I would like to access the right slide from these numbers:
-2 -1 0 1 2 3 4
should match slide:
1 2 0 1 2 0 1
So with index % slidesCount I cover the cases:
0 1 2 3 4
but not negative values. -1 % 3 returns -1 so is slidesCount + index % slidesCount the correct expression if index is negative?
First of, is there a simpler/smarter way to write:
index = index % slidesCount + (index < 0 ? slidesCount : 0)
Now my question is for a slideshow of 3 visible items per slide,
where the last slide may have only one item (index 9 bellow) so from these numbers:
-3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12
I want to match slides:
9 0 3 6 9 0
I hope the following diagram makes sense! Please help me get the correct equation out of it with minimum ifs:
-3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12
|________| |______________________________________________|
|| || ||
|| Math.floor( i / visibleSlides )
Math.ceil(i / visibleSlides) || ||
|| || ||
\/ \/ \/
-1 0 1 2 3 4
|___| |_______________________| |___|
|| || ||
slidesCnt + i % visibleSlides i % visibleSlides || ??
|| || ||
\/ \/ \/
3 0 1 2 3 0
|| i * visibleSlides
\/
9 0 3 6 9 0
in the end, this is how I solved the problem:
// Prevents out of range.
// e.g. -1, -2, 12, 13
let newIndex = (index + slidesCount) % slidesCount
// Calculates how many items are missing on last slide.
// e.g. if 10 slides with 3 visible slides, 2 missing slides on last slide.
let lastSlideItems = slidesCount % visibleSlides || visibleSlides
let missingItems = visibleSlides - lastSlideItems
// If index is negative adjust by adding the missing slides.
newIndex += index < 0 ? missingItems : 0
// Always get the first item of the series of visible items.
// e.g. if index is 8 and 3 visible slides, newIndex will be 6.
newIndex = Math.floor(newIndex / visibleSlides) * visibleSlides
I'm developing a 2D game based on a board of N x M squares (really N x N since it's square). Each square in the board has an ID assigned, starting with ID 0 counting from left-to-right, top-to-bottom.
Example, for a board of 10 x 10
| 0 1 2 3 4 5 6 7 8 9 |
| 10 11 12 13 14 15 16 17 18 19 |
| 20 21 22 23 24 25 26 27 28 29 |
| etc |
| etc |
| etc |
| etc |
| etc |
I would a like a function, which takes the size of the grid (N) and a quadrant (one of [0, 1, 2, 3] corresponding to top-left, top-right, bottom-left, bottom-right), that returns the IDs of the elements in each quadrant. For example, getQuadrant(10, 0) would return the IDs in the top-left quadrant:
[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24... 44]
I've tried a few sequence solvers to find an equation but they're unable to find a match. The only working solutions I've come up with are quadrant dependent, meaning I have essentially have 4 functions.
Summary:
The following expression evaluates to an array of the ids from an nxn square in quadrant quad:
Array.from({length: n * n / 4}).map((_,i) =>
2 * i - i % (n / 2) + (quad % 2) * n / 2 + (quad > 1) * n * n / 2
)
Details:
The function below includes a single formula that allows you to enter N and M for a rectangular grid of any size (N & M must be even), as well as the quadrant number (0 to 3). The first example used is a 6 x 4 grid.
0 1 2 3 4 5
6 7 8 9 10 11
12 13 14 15 16 17
18 19 20 21 22 23
const getRectQuadrant = (n, m, quad) =>
Array.from({length: n/2 * m/2}).map((_,i) =>
2 * i - i % (n / 2) + (quad % 2) * n / 2 + (quad > 1) * n * m / 2
);
console.log(JSON.stringify(getRectQuadrant(6, 4, 0)));
console.log(JSON.stringify(getRectQuadrant(6, 4, 1)));
console.log(JSON.stringify(getRectQuadrant(6, 4, 2)));
console.log(JSON.stringify(getRectQuadrant(6, 4, 3)));
To generalize this to a square grid (i.e. M = N), just create another function that calls that one, i.e. const getSquareQuadrant = (n, quad) => getRectQuadrant(n, n, quad); or just replace every m in the above code with n as shown in the following code for a 4 x 4 square grid:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
const getSquareQuadrant = (n, quad) =>
Array.from({length: n * n / 4}).map((_,i) =>
2 * i - i % (n / 2) + (quad % 2) * n / 2 + (quad > 1) * n * n / 2
);
console.log(JSON.stringify(getSquareQuadrant(4, 0)));
console.log(JSON.stringify(getSquareQuadrant(4, 1)));
console.log(JSON.stringify(getSquareQuadrant(4, 2)));
console.log(JSON.stringify(getSquareQuadrant(4, 3)));
Explanation for the rectangular N x M grid:
Array.from({length: n/2 * m/2}).map((_,i) => ...
This creates a sequence of whole numbers (i.e. starting from zero) whose length is the length of one quadrant, i.e. the length of one quarter of the original grid. These sequential numbers are passed forward as i.
2 * i - i % (n / 2) + (quad % 2) * n / 2 + (quad > 1) * n * m / 2
------------------- ------------------ ----------------------
creates the values adds a constant if adds a constant if you
in the top left you want the right want the bottom half
quadrant half
More verbose/readable version for rectangular grid:
const getRectQuadrant = (m, n, quad) => {
const quadrantPlaceholders = Array.from({length: n/2 * m/2});
const offsetForRightHalf = (quad % 2) * n / 2;
const offsetForBottomHalf = (quad > 1) * n * m / 2;
const idsForQuadrant = quadrantPlaceholders.map((_,i) => {
const idForTopLeft = 2 * i - i % (n / 2);
return idForTopLeft + offsetForRightHalf + offsetForBottomHalf;
});
return idsForQuadrant;
};
console.log(JSON.stringify(getRectQuadrant(4, 6, 0)));
console.log(JSON.stringify(getRectQuadrant(4, 6, 1)));
console.log(JSON.stringify(getRectQuadrant(4, 6, 2)));
console.log(JSON.stringify(getRectQuadrant(4, 6, 3)));
You can create such function using for loop where i is incremented by grid length. Then you just need to slice first or second half of grid based on quadrant parameter.
var data = Array.from(Array(100), (e, i) => e = i)
function getQuadrant(data, n, quad) {
var result = []
for (var i = 0; i < data.length; i += n) {
var p = i + (n / 2)
if (quad == 0 && i < data.length / 2) result.push(...data.slice(i, p))
if (quad == 1 && i < data.length / 2) result.push(...data.slice(p, i + n))
if (quad == 2 && i >= data.length / 2) result.push(...data.slice(i, p))
if (quad == 3 && i >= data.length / 2) result.push(...data.slice(p, i + n))
}
return result
}
console.log(JSON.stringify(getQuadrant(data, 10, 0)))
console.log(JSON.stringify(getQuadrant(data, 10, 1)))
console.log(JSON.stringify(getQuadrant(data, 10, 3)))
This is for Project Euler, problem #5.
The task is to find the smallest number evenly divisible by numbers 1-20. My code seems to work on 1-18, but at 19 my browser starts timing out. This leads me to believe my code is just inefficient.
How can I mitigate this?
function divisible(a){
counter = 0;
result = 2;
while (counter < a){
for (var x = 0; x <= a; x ++){
if (result % x === 0){
counter ++;
}
}
if (counter != a){
counter = 0;
result ++;
}
}
return result;
}
divisible(20)
Basically, you want the least common multiple of 1,...,20.
I would implement lcm by using gcd, which can be implemented using the fast Euclidean algorithm.
function gcd(a, b) {
return b === 0 ? a : gcd(b, a%b); // Euclidean algorithm
}
function lcm(a, b) {
return a * b / gcd(a, b);
}
function divisible(a){
var result = 1;
for(var i=2; i<=a; ++i)
result = lcm(result, i);
return result;
}
divisible(20); // 232792560
Yup, inefficient. You would need to change the algorithm. The most efficient I can think of is to factorise all the numbers from 2 to 20 (with factors and counts: e.g. 18 is 3 * 3 * 2, or twice 3 and once 2, for final { 3: 2, 2: 1 }); then find the maximum for each factor, and multiply them together.
An abbreviated example: the least number that is divisible by 18 and 16:
18: { 3: 2, 2: 1 }
16: { 2: 4 }
maximums of factor repetitions: { 3: 2, 2: 4 }
result: 3^2 * 2^4 = 144
Factorising numbers from 2 to 20 is easy; if you don't know how to do it, there are many possible algorithms, you can see the Wikipedia article on integer factorisation for ideas.
another option with brute force and modulo rest-classification
this problem can be solved with a simple common modulo rest class characteristics.
look at the numbers from 1 to 20 and divide it into two groups and find some unique common attributes between them.
1 2 3 4 5 6 7 8 9 10
we are building a division with the same reminder members
1 divides all
2 divide 4,8 -->>8 important
3 divide 6,9 but 6 doesnt divide 9 evenly--> 6,9
5 divide 10-->> 10 important
that leaves us with 6,7,8,9,10 to check if there is any number from 1 that can divide this with rest 0.
the trick is if 2,4,8 divides a number let say 16 with the same reminder then we don't have to check if 2,4 divides 16, we check only 8.
11 12 13 14 15 16 17 18 19 20
here we can do the same from about with factors of the numbers from above and we will be left with
11 12 13 14 15 16 17 18 19 20
NB: we know that the last number that has to divide the number is 20,
so that means either the solution will be a number ending with 0 or is
one of the factors of 20, so we build factors of 20 and check if 11 12
13 14 15 16 17 18 19 can divide it then we are done.
int start = 20;
while (start % 11 != 0 || start % 12 != 0 | start % 13 != 0 || start % 14 != 0 ||
start % 15 != 0 || start % 16 != 0 || start % 17 != 0 || start % 18 != 0 || start % 19 != 0 )
{
start += 20;
}
console.log(start)
The same idea applies analogue to the first deduction I made to make the
problem seems smaller.
//smallest number divisible by all numbers from 1 to 10
int a = 10;
while (a % 6 != 0 || a % 7 != 0 | a % 8 != 0 || a % 9 != 0 )
{
a += 10;
}
console.log(a)
//smallest number divisible by all numbers from 1 to 5
int i = 5;
while (i % 3 != 0 || i % 4 != 0)
{
i += 5;
}
console.log(i)
This javaScript code block is making me crazy,that how it is doing the computation behind. I try to manually do it with calculator but the results start to be different at 4. Please explain if you know how
function fac(n) {
if (n == 0)
return 1;
else
return fac(n - 1) * n;
}
if i run console.log(fac(1));
// > 1
if i run console.log(fac(2));
// > 2
if i run console.log(fac(3));
// > 6
i was thinking this is what was happening behind
(2-1) * 2 = 2,
(3-1) * 3 = 6,
until i put
(4-1) * 4 = 12.
if i run console.log(fac(4)); the output is 24 not 12
// > 24 how and why?
cheers
It is performing recursive function call to the same function.
function fac(n) {
if (n == 0)
return 1;
else
return fac(n - 1) * n;
}
fac(4);
Value of n is 4. So it should returnfac(4 - 1) * 4). Now fac(4 -1) is calculated before returning the value.
Value of n is 3. Now it will return fac(3 - 1) * 3), which replaces fac(4 - 1) in previous statement. So, it will become fac(3 - 1) * 3 * 4.
Value of n is 2. Now it will return fac(2 - 1) * 2), which replaces fac(3 - 1) in previous statement. So, it will become fac(2 - 1) * 2 * 3 * 4.
Value of n is 1. Now it will return fac(1 - 1) * 1), which replaces fac(2 - 1) in previous statement. So, it will become fac(1 - 1) * 1 * 2 * 3 * 4.
Value of n is 0. Now it will return 1, which replaces fac(1 - 1) in previous statement. So, it will become 1 * 1 * 2 * 3 * 4.
As you can see, you can avoid multiplying by 1 twice by changing your code to
function fac(n) {
if (n == 1)
return 1;
else
return fac(n - 1) * n;
}
In short,
function fac(n) {
return (n == 1) ? 1 : (fac(n - 1) * n);
}
That's a factorial. It's calculates all permutation a set with n elements has. Or simpler:
[factorial] is the product of all positive integers less than or equal to n.
Wikipedia:Factorial
It's noted as n!. For example:
1! = 1
2! = 1 * 2 = 2
3! = 1 * 2 * 3 = 6
4! = 1 * 2 * 3 * 4 = 24
What the function is doing is recursively calling itself. When you execute the function fac(4) the following happens:
At fac(4), since 4 != 0 the value returned is fac(4 -1) * 4. However, since the return function contains a reference to a function, we wait for it to return a value.
At fac(3) (i.e. fac(4-1)), since 3 != 0 the value returned is fac(3-1) * 3. However same thing happens and we wait for result of fac(3-1)/fac(2).
At fac(2) (i.e. fac(3-1)) since 2 != 0 the value returned is fac(2-1) * 2. Again, since we are calling a function we wait for its return until we proceed will calculation.
At fac(1) (i.e. fac(2-1)) since 1 != 0 the value returned is fac(1-1)* 1 and we defer for fac(1-1) to return result.
At fac(0) (i.e. fac(1-1)) since 0==0 we return value one which is neutral for multiplication.
In fac(1), fac(1-1) becomes one, so fac(1) value becomes 1*1 or 1.
In fac(2), fac(2-1) is replaced with 1 so fac(2) becomes 1*2 or 2.
In fac(3), fac(3-1) is replaced with 2, and fac(3) becomes 2*3 or 6.
In fac(4), fac(4-1) is repalced with 6 and fac(4) becomes 6*4 or 24.