For loops seems to run double than what is expected - javascript

I'm having issues with leetcode algo question 1252. I'm not sure why but my for loop seems to run twice. The question is:
"Given n and m which are the dimensions of a matrix initialized by zeros and given an array indices where indices[i] = [ri, ci]. For each pair of [ri, ci] you have to increment all cells in row ri and column ci by 1.
Return the number of cells with odd values in the matrix after applying the increment to all indices."
var oddCells = function(n, m, indices) {
let matrix = [];
let array = Array(m).fill(0);
let k = 0;
while (k < n) {
matrix.push(array);
k++;
}
for (let i = 0; i < indices.length; i++) {
const row = indices[i][0];
const col = indices[i][1];
for (let j = 0; j < n; j++) {
matrix[j][col]++;
}
for (let i = 0; i < m; i++) {
matrix[row][i]++;
}
}
return matrix.flat().filter(number => number % 2 !== 0).length;
}
console.log(oddCells(2, 3, [
[0, 1],
[1, 1]
]));
The specific input I am testing is n = 2, m = 3, indices = [[0,1],[1,1]].
I've tried to follow my code manually but I can't figure out why the two inner for loops are iterating over the nested arrays twice rather than each one once. After the first loop[ the matrix is supposed to be [[1, 2, 1], [0, 1, 0]] but instead I end up with [[1, 3, 1], [1, 3, 1]].

This is a basic problem of reusing mutable reference values.
You are repeatedly pushing the same array to the matrix, so when you modify any value in that array, you are modifying multiple areas of the matrix.
So use separate arrays:
var oddCells = function(n, m, indices) {
let matrix = [];
let k = 0;
while (k < n) {
matrix.push(Array(m).fill(0));
k++;
}
for (let i = 0; i < indices.length; i++) {
const row = indices[i][0];
const col = indices[i][1];
for (let ri = 0; ri < n; ri++) {
matrix[ri][col]++;
}
for (let ci = 0; ci < m; ci++) {
matrix[row][ci]++;
}
}
return matrix.flat().filter(number => number % 2 !== 0).length;
}
console.log(oddCells(2, 3, [
[0, 1],
[1, 1]
]));

Related

How to check if the input matrix is symmetric?

The code below takes in a matrix (MAT) and transposes the matrix, calls it array. The definition of the symmetrical matrix is that it should be a square matrix and the elements in the given matrix compared to the transposed one should be the same.
The given matrix below and transposed matrix should output false if checked for symmetry.
I did create an if statement at first to check whether MAT[j][i] and array[j][i] are the same but keep getting the wrong answer. It's not properly checking all the elements together. Could someone help with that?
Thanks!
const symmetricMatrix = function (MAT) {
let array = [];
for (let i = 0; i < MAT.length; i++) {
array.push([]);
for (let j = 0; j < MAT.length; j++) {
array[i].push(MAT[j][i]);
}
}
return array;
};
console.log(
symmetricMatrix(
(MAT = [
[1, 3, 1],
[-1, 1, 4],
[2, 1, 0],
])
)
);
First you can create a copy of matrix and then transpose it and then check if it has same element at that index.
const symmetricMatrix = function (mat) {
const copy = Array.from(mat, (_) => []);
for (let i = 0; i < mat.length; i++)
for (let j = 0; j < mat.length; j++)
copy[i][j] = mat[j][i];
for (let i = 0; i < mat.length; i++)
for (let j = 0; j < mat.length; j++)
if (copy[i][j] != mat[i][j]) return false;
return true;
};
const matrix = [
[1, 3, 1],
[-1, 1, 4],
[2, 1, 0],
];
const matrix2 = [
[1, -1, 2],
[-1, 1, 1],
[2, 1, 0],
];
console.log(symmetricMatrix(matrix));
console.log(symmetricMatrix(matrix2));

JS for loop in for loop, problem with scope I guess

The input is an array ints [11, 2, 7, 8, 4, 6] and and integer s 10. The function is to output an array with a pair of two numbers from ints which first form a sum of 10. So here the output should be [2, 8], because 2 + 8 = 10. Why does it output empty array? The arrResults was updated in the nested for loop, so why doesn't it show up like that after the final return statement?
function sumPairs(ints, s) {
let arrResults = [];
let sumOfTwo;
for (i = 0; i < ints.length; i++) {
for (j = 0; j < ints.length; j++) {
sumOfTwo = ints[i] + ints[j];
if (sumOfTwo === s) {
arrResults.push(ints[i]);
arrResults.push(ints[j]);
break;
}
}
if (arrResults !== []) {
break;
}
}
return arrResults;
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
Beside the wrong comparing of an array with another array (without having the same object reference)
a = []
b = []
a === b // false
// other example
a = []
b = a
a === b // true
for checking the length,
a = []
a.length // 0
and by using a nearly quadratic time complexity of n², even with looping
i = 0; i < array.length - 1
j = i + 1; j < array.length
which is more then the half of n², but strill quadratic,
you could take a single loop with an object fo already seen values.
This approach finds the first pair of the array for a certain sum.
function sumPairs(ints, s) {
const needed = {};
for (const value of ints) {
if (needed[value]) return [s - value, value];
needed[s - value] = true;
}
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
Your code fails because you are checking to see if the array is empty. The problem is that check is never going to be false, so it exits on the first iteration.
console.log([]===[]);
console.log([]!==[]);
So code with changes to improve performance and to exit out
function sumPairs(ints, s) {
let arrResults = [];
let sumOfTwo;
for (let i = 0; i < ints.length; i++) {
for (let j = i + 1; j < ints.length; j++) {
sumOfTwo = ints[i] + ints[j];
if (sumOfTwo === s) {
arrResults.push(ints[i]);
arrResults.push(ints[j]);
break;
}
}
if (arrResults.length) {
break;
}
}
return arrResults;
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));
There is no need to break out twice, just return the array
function sumPairs(ints, s) {
let arrResults = [];
let sumOfTwo;
for (let i = 0; i < ints.length; i++) {
for (let j = i + 1; j < ints.length; j++) {
sumOfTwo = ints[i] + ints[j];
if (sumOfTwo === s) {
return [ints[i], ints[j]];
}
}
}
return null;
}
console.log(sumPairs([11, 2, 7, 8, 4, 6], 10));

Iterate over shallow copy of nested array in Javascript

I have a nested array:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
I need to iterate over the first and second element of every nested array and update the changes on the original array. How do I achieve this? I have tried many options but the results don't update the original array. For example:
let arrayCop = [];
for (let i = 0; i <= 1; i++) {
for (let j = 0; j <= 1; j++) {
arrayCop.push(array[i][j]);
}
}
arrayCop.forEach(...);
Thanks.
This is my full code, I'm trying to build a legal sudoku generator:
let sudoku = [];
function populateSudoku() {
let array = [];
while (array.length <= 8) {
let randomNum = Math.floor(Math.random() * 9 + 1);
array.push(randomNum);
if (array.indexOf(randomNum) < array.lastIndexOf(randomNum)) {
array.pop()
}
}
return array;
}
while (sudoku.length <= 8) {
sudoku.push(populateSudoku());
}
for (let i = 0; i < sudoku.length; i++) {
for (let j = 0; j < sudoku.length; j++) {
sudoku[i].forEach(element => {
if (sudoku[i].indexOf(element) === sudoku[j].indexOf(element) &&
(i !== j)) {
sudoku[j][sudoku[i].indexOf(element)] = 0;
}
})
}
}
let array = [];
for (let i = 0; i <= 2; i++) {
for (let j = 0; j <= 2; j++) {
array.push(sudoku[i][j]);
}
}
array[3] = 452345;
console.log(sudoku);
**
# I did it! #
**
let array = [[1, 2, 3], [7, 4, 1], [2, 4, 3]];
// checks for duplicates just in first and second item of every file
for (let i = 0; i <= 1; i++) {
for (let j = 0; j <= 2; j++) {
array[i].forEach((element, index) => {
if ((i !== j) && index <= 1 &&
(array[j].indexOf(element) >= 0 && array[j].indexOf(element) <= 1)) {
array[i][index] = 'x';
}
})
}
}
console.log(array);
If I understand right, you would like to change the original array to:
[[1, 2], [4, 5], [7, 8]]
If so, this would do it:
array.forEach(element => element.splice(2))
You can use Array.prototype.map function
ORIGINAL
I need to iterate over the first and second element of every nested
array and update the changes on the original array
function iterate(array) {
array.forEach(function(element, index) {
console.log('[' + index + "][0]", element[0]);
console.log('[' + index + "][1]", element[1])
})
}
Not sure what you mean by update changes to the original array, though...
EDIT
Alright, after looking through other answers, I believe #NinaW got what you were looking for.
function parse(array) {
array.forEach(function(element) { element.slice(0, 2) })
}
Use flatMap and destructuring.
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
let arrayCop = array.flatMap(([first, second]) => [first, second]);
console.log(arrayCop)
let array = [[1, 2, 3], [7, 4, 1], [2, 4, 3]];
console.log(array);
// checks for duplicates just in first and second item of every file
for (let i = 0; i <= 1; i++) {
for (let j = 0; j <= 2; j++) {
array[i].forEach((element, index) => {
if ((i !== j) && index <= 1 &&
(array[j].indexOf(element) >= 0 && array[j].indexOf(element) <= 1)) {
array[i][index] = 'x';
}
})
}
}
console.log(array);

How to get all substrings (contiguous subsequences) of my JavaScript array?

My task is to split the given array into smaller arrays using JavaScript. For example [1, 2, 3, 4] should be split to [1] [1, 2] [1, 2, 3] [1, 2, 3, 4] [2] [2, 3] [2, 3, 4] [3] [3, 4] [4].
I am using this code:
let arr = [1, 2, 3, 4];
for (let i = 1; i <= arr.length; i++) {
let a = [];
for (let j = 0; j < arr.length; j++) {
a.push(arr[j]);
if (a.length === i) {
break;
}
}
console.log(a);
}
And I get the following result: [1] [1, 2] [1, 2, 3] [1, 2, 3, 4] undefined
What am I missing/doing wrong?
For the inner array, you could just start with the index of the outer array.
var array = [1, 2, 3, 4],
i, j, l = array.length,
result = [];
for (i = 0; i < l; i++) {
for (j = i; j < l; j++) {
result.push(array.slice(i, j + 1));
}
}
console.log(result.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You have two issues in your code:
You need to have loop to initialize with the value of i for the inner loop so that it consider the next index for new iteration of i
You need to remove that break on the length which you have in inner loop.
let arr = [1, 2, 3, 4];
for (let i = 0; i <= arr.length; i++) {
let a = [];
for (let j = i; j < arr.length; j++) {
a.push(arr[j]);
console.log(a);
}
}
Try this
let arr = [1, 2, 3, 4];
for (let i = 0; i <= arr.length; i++) {
let a = [];
for (let j = i; j < arr.length; j++) {
a.push(arr[j]);
console.log(a);
}
}
If you don't want to mutate your array.
let arr = [1, 2, 3, 4];
let res = [];
for (let i = 0; i <= arr.length; i++) {
let a = [];
for (let j = i; j < arr.length; j++) {
a = [...a, arr[j]];
res = [...res, a];
}
}
console.log(res);
i have prepare stackblitz for this case.
let source = [1,2,3,4];
const output = [];
const arrayMultiplier = (source) => {
const eachValueArray = [];
source.forEach((item, index) => {
// Will push new array who will be sliced source array.
eachValueArray.push(source.slice(0, source.length - index));
});
//We reverse array to have right order.
return eachValueArray.reverse();
};
for(let i = 0; i <= source.length; i++) {
output.push(...arrayMultiplier(source));
source.shift(); // Will recraft source array by removing first index.
}
//Don't forget last item.
output.push(source);
console.log(output);
Is not the most shorten solution but do the job
== update after code review ==
// [...]
const arrayMultiplier = (source) => {
// Will push new array who will be sliced source array.
// We reverse array to have right order.
return source.map((item, index) => source.slice(0, source.length - index)).reverse();
};
// [...]
Use two iteration
get slice array based on loop index.
use sliced array and combine array element.
var arr = [1, 2, 3, 4];
let newArra =[];
arr.map((x,i)=> {
let remainArr = arr.slice(i);
return remainArr.forEach((y, r) => newArra.push(remainArr.slice(0, r+1)))
})
newArra.forEach(x=> console.log(x))

Group items in for loops

Using JavaScript, I am looping through an array of values.
var values = [1, 2, 1, 3, 1, 3, 4, 1]
for (let i = 0; i < values.length; i++) {
console.log(values[i])
}
I want to get the sum for each group of 4. I could do this in multiple for loops by using:
var values = [1, 2, 1, 3]
var sum1 = 0
for (let i = 0; i < values.length; i++) {
sum1 += parseInt(values[i]);
}
var values = [1, 3, 4, 1]
var sum2 = 0
for (let i = 0; i < values.length; i++) {
sum2 += parseInt(values[i]);
}
How can I group by 4 and get the sum of the values for each group by using one for loop?
Can slice() the array and reduce() each sub array
var values = [1, 2, 1, 3, 1, 3, 4, 1]
var sums =[];
for(let i=0; i< values.length; i=i+4){
const subArr= values.slice(i,i+4);
const sum = subArr.reduce((a,c)=>a+c)
sums.push(sum)
}
console.log(sums)
You can use a counter. Reset the counter and sum variable when it reaches the group limit, like below example :
var values = [1, 2, 1, 3, 1, 3, 4, 1];
var result = [];
var counter = 0;
var sum = 0;
for(var i = 0; i < values.length; i++){
counter++;
sum += values[i];
if(counter === 4 || i === values.length-1){
result.push(sum);
counter = 0;
sum = 0;
}
}
console.log(result);
You could take an array as result set and divide the index by 4 and take the integer value for adding the value.
var values = [1, 2, 1, 3, 1, 3, 4, 1],
grouped = values.reduce((r, v, i) => {
var k = Math.floor(i / 4);
r[k] = r[k] || 0;
r[k] += v;
return r;
}, []);
console.log(grouped);

Categories

Resources