What realization is faster and why - javascript

I wrote a function that calculate this value/formula:
and I have 2 realizations, and I don't understand, why realization with 3 loops is working faster than realization with if's?
Please, explain to me why is that?
If's realization:
function res(p, square) {
let res = 0
let i = 1;
let j = 1;
let k = 1;
label: for (;;) {
res += (i ** 3 * j ** 2 * k)
if (k < p) {
k++
continue label
}
if (j < p) {
k = 1
j++
continue label
}
if (i < p) {
k = 1
j = 1;
i++
continue label
}
if (k == p && j == p && i == p) {
return res
}
}
}
Loop realization:
function res1(p) {
let res = 0
for (let i = 0; i <= p; i++) {
for (let j = 0; j <= p; j++) {
for (let k = 0; k <= p; k++) {
res += (i ** 3 * j ** 2 * k)
}
}
}
return res
}

Related

Storing instances of an array using the slice method in javascript

I have an array list I loop over and modify it each time. I want to store all instances of my list array in an other array I named allLists, and to do so, I'm using the slice method.
It seems to work in the simple example below:
let list=[1,2,3,4];
let allList = [];
allList.push(list.slice());
list[2]=6;
allList.push(list.slice());
console.log(allList);// returns [1,2,3,4] [1,2,6,4]
But it doesn't work in the following code. Instead, allLists is filled with the last instance of the list array.
let list = Array.from({
length: 9
}, () => Array.from({
length: 9
}, () => [1, 2, 3, 4, 5, 6, 7, 8, 9]));
let allLists = [list.slice()];
let indexList = [];
let lengthList = [];
let key = true;
function handleNewIndex(list) {
let newIndex = [0, 0];
let maxLength = 9;
for (let i = 0; i < list.length; i++) {
for (let j = 0; j < list.length; j++) {
if (list[i][j].length < maxLength && list[i][j].length > 0) {
maxLength = list[i][j].length;
newIndex = [i, j];
}
}
}
return newIndex;
}
function isSudokuValid(list) {
for (let i = 0; i < list.length; i++) {
for (let j = 0; j < list.length; j++) {
if (list[i][j].length === 0) {
return false;
}
}
}
return true;
}
function handleWrongSudoku(allLists, indexList, lengthList) {
let counter = 1;
while (lengthList[lengthList.length - counter] <= 1) {
counter = counter + 1;
allLists.pop();
indexList.pop();
}
let wrongList = allLists.pop();
list = allLists.pop();
indexLine = indexList[indexList.length - 1][0];
indexColumn = indexList[indexList.length - 1][1];
let wrongNumber = wrongList[indexLine][indexColumn];
for (let i = 0; i < list[indexLine][indexColumn].length; i++) {
if (list[indexLine][indexColumn][i] != wrongNumber) {
list[indexLine][indexColumn] = list[indexLine][indexColumn][i];
}
}
allLists.push(list.slice());
indexLine = handleNewIndex(list)[0];
indexColumn = handleNewIndex(list)[1];
}
function generateSudoku() {
let indexLine = Math.floor(Math.random() * 9);
let indexColumn = Math.floor(Math.random() * 9);
let counter = 0;
while (counter < 81) {
indexList.push([indexLine, indexColumn]);
let bigSquareIndex = 3 * Math.floor(indexLine / 3) + Math.floor(indexColumn / 3);
lengthList.push(list[indexLine][indexColumn].length);
list[indexLine][indexColumn] = list[indexLine][indexColumn][Math.floor(Math.random() * list[indexLine][indexColumn].length)];
counter = counter + 1;
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (3 * Math.floor(i / 3) + Math.floor(j / 3) === bigSquareIndex) {
let k = 0;
let n = list[i][j].length;
while (list[i][j][k] != list[indexLine][indexColumn] && k < n) {
k = k + 1;
}
if (k < n) {
list[i][j].splice(k, 1);
}
} else if (i === indexLine || j === indexColumn) {
let k = 0;
let n = list[i][j].length;
while (list[i][j][k] != list[indexLine][indexColumn] && k < n) {
k = k + 1;
}
if (k < n) {
list[i][j].splice(k, 1);
}
}
}
}
allLists.push(list.slice());
key = isSudokuValid(list);
if (key === false) { //ignore this scenario, not done yet, assume key = true at all time
console.log(key, lengthList, indexList, allLists);
handleWrongSudoku(allLists, indexList, lengthList);
key = true;
//return;
} else {
indexLine = handleNewIndex(list)[0];
indexColumn = handleNewIndex(list)[1];
}
}
}
generateSudoku();
console.log(allLists); // returns 81 times the same 9x9 array instead of the 81 different instances of the list array
I don't know what I'm doing wrong here.
Thanks for the hint Code Maniac.
I used the JSON method instead to create a deep copy and it's working fine now.
allLists.push(JSON.parse(JSON.stringify(list)));
This post explains the difference between shallow and deep copy:
https://www.freecodecamp.org/news/how-to-clone-an-array-in-javascript-1d3183468f6a/

Common Multiple With For Loop

I want to get the common multiple in any given array, the problem i think is in my loop condition i dont want j to be less than 30, i want j to keep multiplying until the common multiple is found you can see the desired output down, how can i do this? thanks in advance.
function m(arr){
for(let i = 0; i < arr.length; i++){
console.log(`when arr[i] = `, i);
for(let j = arr[arr.length - 1]; j < 30; j += arr[arr.length - 1]) {
if(j % arr[i] === 0) console.log(j)
}
}
}
m([2,3,4,5])
this code outputs:
when arr[i] = 2
10
20
when arr[i] = 3
15
when arr[i] = 4
20
when arr[i] = 5
5
10
15
20
25
desired output
when arr[i] = 2
60
when arr[i] = 3
60
when arr[i] = 4
60
when arr[i] = 5
60
According to #Prosy Arceno's suggestion extended a little.
Thanks Prosy.
function m(arr) {
let m = multiply( arr )
for (let i = 0; i < arr.length; i++) {
console.log(`when arr[i] = `, i);
for (let j = arr[ arr.length - 1 ] ; j < m ; j++) {
let result = arr.every(function (element) {
return j % element === 0;
});
if (result) { console.log(j); break }
}
}
}
multiply =( arr )=>{
let m = 1
arr.map( element =>{ m = m * element } )
return m
}
m([2, 3, 4, 5 , 18]);
I think that your general approach is a bit problematic. Your inner for loop searches for the first common multiple of your current arr[i] and the last element of the array arr[arr.length-1].
In your example, this boils down to the inner loop logging a 10 because it is the first common multiple of 2 and 5.
There are many ways to solve your problem (see https://en.wikipedia.org/wiki/Least_common_multiple)
You may use every method of Array.
function m(arr) {
for (let i = 0; i < arr.length; i++) {
console.log(`when arr[i] = `, i);
for (let j = arr[ arr.length - 1 ] ; j < 100; j++) {
let result = arr.every(function (element) {
return j % element === 0;
});
if (result) { console.log(j); }
}
}
}
m([2, 3, 4, 5]);
function m(arr) {
for (let i = 0; i < arr.length; i++) {
console.log(`when arr[i] = `, i);
for (let j = 5; j < 100; j++) {
let result = arr.every(function (element) {
return j % element === 0;
});
if (result) console.log(j);
}
}
}
m([2, 3, 4, 5]);

Is there a way to extend JavaScript call stack size?

I have tried setting Error.stackTraceLimit = Infinity in chrome and firefox, but no effect.
I'm just trying to multiply two matrixes in a recursive way.
it breakes at the point of a [32][32] matrix.
Here is the code that i run, a simple devide and conquer matrix multiplication
first i generate 2 random matrices and then multiply them
function divideConquer(a, b) {
var i = 0,
j = 0,
k = 0;
var c = [];
let row = [];
// creating the output
for (let l = 0; l < a.length; l++) {
row = [];
for (let m = 0; m < b[0].length; m++) {
row.push(parseInt(0));
}
c.push(row);
}
multiplyRecursion(a, b);
return c;
function multiplyRecursion(a, b) {
// If all rows traversed
if (i >= a.length)
return;
// If i < row1
if (j < b[0].length) {
if (k < a[0].length) {
c[i][j] += a[i][k] * b[k][j];
k++;
multiplyRecursion(a, b);
}
k = 0;
j++;
multiplyRecursion(a, b);
}
j = 0;
i++;
multiplyRecursion(a, b);
}
}
function generateRandomMatrix(n) {
let row = [],
matrix = [];
for (let i = 0; i < n; i++) {
row = [];
for (let j = 0; j < n; j++) {
row.push(Math.floor(Math.random() * 10));
}
matrix.push(row);
}
return matrix;
}
let a = generateRandomMatrix(32);
let b = generateRandomMatrix(32);
console.log(divideConquer(a, b));

Combinations of n words from array of m words - Javascript

Given arr = ['mat','cat','fat']
A function getComb(arr, n = 2) where n is the number of words each combination must have.
Expected results:
mat cat
mat fat
cat fat
I could not modify the code below any further to get the desired results. Any idea? thx
Thanks to Knskan3:
'getCombinations': (arr, n) => {
let i, j, k, elem, l = arr.length, childperm, ret = [];
if (n === 1) {
for (let i = 0; i < arr.length; i++) {
ret.push([arr[i]]);
}
return ret;
}
else {
for (i = 0; i < l; i++) {
elem = arr.shift();
for (j = 0; j < elem.length; j++) {
childperm = lib.getCombinations(arr.slice(), n - 1);
for (k = 0; k < childperm.length; k++) {
ret.push([elem[j]].concat(childperm[k]));
}
}
}
return ret;
}
},
I suggest a space-efficient generator function:
// Generate all k-combinations of first n array elements:
function* combinations(array, k, n = array.length) {
if (k < 1) {
yield [];
} else {
for (let i = --k; i < n; i++) {
for (let combination of combinations(array, k, i)) {
combination.push(array[i]);
yield combination;
}
}
}
}
// Example:
console.log(...combinations(['mat', 'cat', 'fat'], 2));

JavaScript arrays - Finding the number of combinations of 2 elements

I come from a Ruby background, which features an enumerable class. In Ruby, I can easily find combinations of array elements.
array.combination(2).count
I know that JavaScript doesn't feature such built in functions, so I was wondering how I could implement this in JS. I was thinking something like
I have an array as follows
var numbers = [9,7,12]
var combos = []
for (var i = 0; i < numbers.length; i++) {
combos.push([numbers[i], numbers[i+1])
}
By the way, the possible combos are
[9,7], [9,12] and [7,12]
so by calling the length function on this array, 3 would be returned.
Any ideas?
How about:
for (var i = 0; i < numbers.length; i++)
for (var j = i + 1; j < numbers.length; j++)
combos.push([numbers[i], numbers[j]]);
Are you strictly talking about 2-combinations of the array or are you interested in a k-combinations solution?
Found this in this gist
function k_combinations(set, k) {
var i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
// Assert {1 < k < set.length}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
Here's a recursive function, which should work for any number:
function combination(arr, num) {
var r= [];
for(var i = 0 ; i < arr.length ; i++) {
if(num===1) r.push([arr[i]]);
else {
combination(arr.slice(i+1), num-1).forEach(function(val) {
r.push([].concat(arr[i], val));
});
}
}
return r;
} //combination
Working Fiddle

Categories