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]]
Related
I was researching solution to the Sudoku Solution Validator algorithm and came across this example. The code works and validates but what I do not understand is why in the for loops to get to validate a block there is a N-2? If N = 9 and the board is 9 * 9 then why would that need to be changed to 7?
When I remove the -2 and just leave N I do not see any changes in my console.
Here is the link https://www.geeksforgeeks.org/check-if-given-sudoku-solution-is-valid-or-not/
Thank you!!
<script>
// JavaScript program to implement
// the above approach
var N = 9;
// Function to check if all elements
// of the board[][] array store
// value in the range[1, 9]
function isinRange(board)
{
// Traverse board[][] array
for(var i = 0; i < N; i++)
{
for(var j = 0; j < N; j++)
{
// Check if board[i][j]
// lies in the range
if (board[i][j] <= 0 ||
board[i][j] > 9)
{
return false;
}
}
}
return true;
}
// Function to check if the solution
// of sudoku puzzle is valid or not
function isValidSudoku(board)
{
// Check if all elements of board[][]
// stores value in the range[1, 9]
if (isinRange(board) == false)
{
return false;
}
// Stores unique value
// from 1 to N
var unique = Array(N+1).fill(false);
// Traverse each row of
// the given array
for(var i = 0; i < N; i++)
{
unique = Array(N+1).fill(false);
// Traverse each column
// of current row
for(var j = 0; j < N; j++)
{
// Stores the value
// of board[i][j]
var Z = board[i][j];
// Check if current row
// stores duplicate value
if (unique[Z])
{
return false;
}
unique[Z] = true;
}
}
// Traverse each column of
// the given array
for(var i = 0; i < N; i++)
{
// Initialize unique[]
// array to false
unique = Array(N+1).fill(false);
// Traverse each row
// of current column
for(var j = 0; j < N; j++)
{
// Stores the value
// of board[j][i]
var Z = board[j][i];
// Check if current column
// stores duplicate value
if (unique[Z])
{
return false;
}
unique[Z] = true;
}
}
// Traverse each block of
// size 3 * 3 in board[][] array
for(var i = 0; i < N - 2; i += 3) //<====== what is the point of N-2? What is it doing?
{
// j stores first column of
// each 3 * 3 block
for(var j = 0; j < N - 2; j += 3) //<====== what is the point of N-2? What is it doing?
{
// Initialize unique[]
// array to false
unique = Array(N+1).fill(false);
// Traverse current block
for(var k = 0; k < 3; k++)
{
for(var l = 0; l < 3; l++)
{
// Stores row number
// of current block
var X = i + k;
// Stores column number
// of current block
var Y = j + l;
// Stores the value
// of board[X][Y]
var Z = board[X][Y];
// Check if current block
// stores duplicate value
if (unique[Z])
{
return false;
}
unique[Z] = true;
}
}
}
}
// If all conditions satisfied
return true;
}
// Driver Code
var board = [ [ 7, 9, 2, 1, 5, 4, 3, 8, 6 ],
[ 6, 4, 3, 8, 2, 7, 1, 5, 9 ],
[ 8, 5, 1, 3, 9, 6, 7, 2, 4 ],
[ 2, 6, 5, 9, 7, 3, 8, 4, 1 ],
[ 4, 8, 9, 5, 6, 1, 2, 7, 3 ],
[ 3, 1, 7, 4, 8, 2, 9, 6, 5 ],
[ 1, 3, 6, 7, 4, 8, 5, 9, 2 ],
[ 9, 7, 4, 2, 1, 5, 6, 3, 8 ],
[ 5, 2, 8, 6, 3, 9, 4, 1, 7 ] ];
if (isValidSudoku(board))
{
document.write("Valid");
}
else
{
document.write("Not Valid");
}
</script>
Sudoku contains sub blocks each is 3X3
So the code loops over the first cell in each sub block then iterate over the each sub-block cell.
The author of the code added N-2 condition so when he iterate over the sub-block cells
Var X = i+k; he make sure he doesn't access out of bound cell.
How ever when the number of columns and number of rows in sudoku are multiple of 3 this check is useless.
That's why you see no difference when you remove -2.
This is because the code is working in steps of 3
for(var i = 0; i < N - 2; i += 3)
You can see i += 3
so i = 0, 3, 6
as N = 9 -> 9-2 = 7 -> 6 is bigger than 7
Later in teh code you can see loop k & l, this is taking care of the 3x3 matrix
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'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);
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
How can I make a sum of values in same row and column and make another array (can be one-dimensional) of results.
Array [
[ 1, 1, 0, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 0, 1 ]
]
var res = []; //the 1D array to hold the sums
var hArr = [
[ 1, 1, 0, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 0, 1 ]
]; //your array
var vArr = []; //Now lets create an array of arrays with the columns of hArr
for (var j=0; j<hArr[0].length; j++) {
var temp = [];
for (var i=0; i<hArr.length; i++) {
temp.push(hArr[i][j]);
}
vArr.push(temp);
}
//sum all the element in the line - Vertically and Horizontally
function SumVH (hInd, vInd) {
var sum = 0;
//add horizontal elements
for(var i=0; i<hArr[hInd].length; i++) {
sum += hArr[hInd][i];
}
//add vertical elements
for(var i=0; i<vArr[vInd].length; i++) {
sum += vArr[vInd][i];
}
//console.log("hInd="+hInd+" vInd="+vInd+" Sum="+sum);
return sum;
}
// go through the main array and get result
var sumR = 0;
//sum of each row
for (var i=0; i<hArr.length; i++) {
for (var j=0; j<hArr[i].length; j++) {
sumR = SumVH(i,j) - (2 * hArr[i][j]);
res.push(sumR);
}
}
Please check it now. The variable res holds the result
For my array writen above I want result array like 7, 7, 5, 7, 8, 8,
6, 8, 8, 8, 6, 8, 7, 7, 5, 7
Now the above code does not count the number itself in sum. But to get the result as your comment, please replace this line
sumR = SumVH(i,j) - (2 * hArr[i][j]);
with
sumR = SumVH(i,j);
Thank you.