how to fill numbers in these arrays?
[
[ 0 ],
[ 0, 0 ],
[ 0, 0, 0 ],
[ 0, 0, 0, 0 ]
]
what i got for nested loops, the numbers i fill is same like the numbers of target(num) ; it repeats numbers target(num) in those arrays
looks below:
var arr = [
[0],
[0, 0],
[0, 0, 0],
[0, 0, 0, 0]
]
var num = 20
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
for (var k = 0; k <= num; k++) {
arr[i][j] = k
}
}
};
console.log(arr)
the output i want is like this :
[
[ 1 ],
[ 3, 5 ],
[ 7, 9, 11 ],
[ 13, 15, 17, 19 ]
]
can anyone explain why my codes repeat the same number ? unlike the output i want
In the innermost loop, you're reassigning arr[i][j] = k over and over again, until k reaches 20. So, every time the innermost loop is reached, arr[i][j] becomes 20.
You only need 2 loops: an outer (loop over arr) and an inner one (loop over each subarray), while keeping a persistent counter outside:
var arr = [
[0],
[0, 0],
[0, 0, 0],
[0, 0, 0, 0]
];
var counter = 1;
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
arr[i][j] = counter;
counter++;
}
}
console.log(arr);
(also note that a for loop's } should not have a ; after it)
To display only odd numbers:
var arr = [
[0],
[0, 0],
[0, 0, 0],
[0, 0, 0, 0]
];
var counter = 1;
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
arr[i][j] = counter;
counter += 2;
}
}
console.log(arr);
You can do it with a variable to keep track of value to be inserted and map
var arr = [[ 0 ],[ 0, 0 ],[ 0, 0, 0 ],[ 0, 0, 0, 0 ]]
let value = 0;
let op= arr.map(e=>{
return e.map(el=> el=++value)
})
console.log(op)
var arr = [
[0],
[0, 0],
[0, 0, 0],
[0, 0, 0, 0]
]
var num = 20
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
for (var k = 0; k <= num; k++) {
arr[i][j] = k
}
}
};
console.log(arr)
The third for loop always executing code 20 times.Therefor every index of array store the last looping value i.e 20
Related
I was just trying stuff out in Vanilla JS and ran into a problem where array.push does not push another array (row) whose elems got changed in a for loop, but rather replaces the whole array (mainArr). It would be better to show the code so please scroll below
function genArray(m, n) {
let mainArr = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row.push(j);
}
mainArr.push(row)
}
return mainArr;
}
let myArr = genArray(3, 2);
console.log(myArr);
/**
* outputs:
*
* [ [ 0, 1, 0, 1, 0, 1 ],
* [ 0, 1, 0, 1, 0, 1 ],
* [ 0, 1, 0, 1, 0, 1 ] ]
*
* why not:
*
* [ [ 0, 1 ],
* [ 0, 1, 0, 1 ],
* [ 0, 1, 0, 1, 0, 1 ] ]
*/
At first I thought it was just because of the reference being appended as this SOF answers says, but as the code shows it doesn't.
let arr1 = []
let arr2 = [1, 2]
arr1.push(arr2)
console.log(arr1); // [ [ 1, 2 ] ]
arr2 = [2, 4]
console.log(arr1); // still [ [ 1, 2 ] ]
let arr3 = []
let obj1 = {name: "John"}
arr3.push(obj1)
console.log(arr3); // [ {name: "John"}]
obj1.name = "Mike"
console.log(arr3); // [ {name: "Mike"} ]
You are updating the same array every time, so all inserted lists will eventually point to the same reference with the value set in the last iteration.
The following is a fix with an enhancement to reach the expected output:
function genArray(m, n) {
const mainArr = [];
for (let i = 0; i < m; i++) {
const row = [];
let count = i;
while(count-- >= 0) {
for (let j = 0; j < n; j++) {
row.push(j);
}
}
mainArr.push(row)
}
return mainArr;
}
console.log( genArray(3, 2) );
You can use Destructuring assignment instead of array.push.
just like this:
function genArray(m, n) {
let mainArr = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row=[...row,j];
}
mainArr.push(row)
}
return mainArr;
}
let myArr = genArray(3, 2);
console.log(myArr);
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));
I want to get the summation of 2d array per column, and i don't know why it's adding everything.
let vals = [
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]
];
total = 0;
for (let i = 0; i < vals.length; i++) {
for (let j = 0; j < vals.length; j++) {
total += vals[j][i];
}
console.log(total);
}
output:
3
6
9
what i need:
3
3
3
let vals = [[1, 1, 1], [1, 1, 1], [1, 1, 1]];
total = 0;
for (let i = 0; i < vals.length; i++) {
for (let j = 0; j < vals.length; j++) {
total += vals[j][i];
}
console.log(total);
}
let vals = [[1, 1, 1], [1, 1, 1], [1, 1, 1]];
total = 0;
for (let i = 0; i < vals.length; i++) {
for (let j = 0; j < vals.length; j++) {
total += vals[j][i];
}
console.log(total);
total = 0;
}
you need to reset total after inner loop is finished.
You have to initialize total for each row.
let vals = [[1, 1, 1], [1, 1, 1], [1, 1, 1]];
for (let i = 0; i < vals.length; i++) {
let total = 0;
for (let j = 0; j < vals.length; j++) {
total += vals[j][i];
}
console.log(total);
}
I've been working at this all day, and I can't work out why this algorithm doesn't cover the entire grid when starting at position grid[1][1].
I start by setting up the grid and calculating the number of rows and columns in the grid to give me a limit on the edges of the array.
I then call the function, setting position grid[1][1] = 1, calculating the offset and making sure it is not outside the array and making sure the new position has not already been called before calling the function recursively.
I just can't figure out why this isn't working!
var grid = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]];
var cols = grid.length;
var rows = grid[0].length;
floodFill(1, 1)
function floodFill(col, row) {
grid[col][row] = 1;
for (c_off = -1; c_off < 2; c_off++) {
for (r_off = -1; r_off < 2; r_off++) {
var i = col + c_off;
var j = row + r_off;
if (i > -1 && i < cols && j > -1 && j < rows) {
if (grid[i][j] != 1) {
floodFill(i, j);
}
}
}
}
}
grid;
/*
output:
[ [ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 0 ],
[ 1, 1, 0, 0, 0 ] ]
expected output:
[ [ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ] ]
*/
That's because c_off and r_off are not defined as local variables (via the var or let keywords) so they are treated like a global variables which means that a recursive invocation of floodFill() overwrites the values for its calling invocation thereby interfering with the caller's iteration order.
The fix is simple: just add a var keyword in both for loops:
function floodFill(col, row) {
grid[col][row] = 1;
for (var c_off = -1; c_off < 2; c_off++) {
for (var r_off = -1; r_off < 2; r_off++) {
var i = col + c_off;
var j = row + r_off;
if (i > -1 && i < cols && j > -1 && j < rows) {
if (grid[i][j] != 1) {
floodFill(i, j);
}
}
}
}
}
Appendix
You can move the detection of out-of-grid condition, and the check whether the given point is already filled, to the beginning of the function (instead of doing it just before the recursive call). Some may argue that the resulting code is simpler to understand:
function floodFill(col, row) {
if (col < 0 || col >= cols || row < 0 || row >= rows) {
return;
}
if (grid[col][row] == 1) {
return;
}
grid[col][row] = 1;
for (var c_off = -1; c_off < 2; c_off++) {
for (var r_off = -1; r_off < 2; r_off++) {
floodFill(col + c_off, row + r_off);
}
}
}
I think Itay Maman answer is probably better. I solved it this way. by changing c_off < 5 and r_off < 5
var grid = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]];
var cols = grid.length;
var rows = grid[0].length;
floodFill(1, 1)
function floodFill(col, row) {
grid[col][row] = 1;
for (c_off = -1; c_off < 5; c_off++) {
for (r_off = -1; r_off < 5; r_off++) {
var i = col + c_off;
var j = row + r_off;
if (i > -1 && i < cols && j > -1 && j < rows) {
if (grid[i][j] != 1) {
floodFill(i, j);
}
}
}
}
}
console.log(grid);
I'm creating a simple breakout clone using HTML5 Canvas and have come across the loadHitGrid() function, but I'm having difficulty understanding what it does.
It looks like its creating arrays within the hitgrid array
and then filling this with 1's
Can someone help or draw this out?
function loadHitGrid() {
for (var i = 0; i < NUM_ROWS; i++) {
hitGrid[i] = new Array;
for (var j = 0; j < NUM_COLS; j++) {
hitGrid[i][j] = 1;
}
}
}
//Can i replace hitGrid with the following?
hitGrid = [
1, 1, 1, 1, 1, // is this the same as the above????
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1
]
function drawblocks() {
for (var i = 0; i < NUM_ROWS; i++) { // loops trough number of rows
for (var j = 0; j < NUM_COLS; j++) { // loops thgrough number of cols
if (hitGrid[i][j] == 1) { // for each row / col check for 1
ctx.beginPath(); // Satrts a new path used when drawing!
ctx.fillStyle = colours[i];
ctx.fillRect(j * (blockW + SPACING) + SPACING,
i * (blockH + SPACING) + SPACING, blockW, blockH);
}
}
}
This would be :
hitGrid = [[1, 1, 1, 1, 1], // is this the same as the above????
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]];
Of course that means that NUM_ROWS, and NUM_COLUMNS is 5 :)
Check out my comments on the code below:
function loadHitGrid () {
for(var i = 0 ; i < NUM_ROWS ; i ++) {
hitGrid[i] = new Array; //Creating an empty array NUM_ROWS amount of times
for(var j = 0; j < NUM_COLS; j ++) {
hitGrid[i][j] = 1 ; //Populating each newly created empty array with NUM_COLS amount of ones.
}
}
}
So in NUM_ROWS and NUM_COLS both equal 5 and assuming hitGrid was an empty array, the output would look more like:
[[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]]