I'm a new javascript developer from lua and I have some confusion about arrays. I'm trying to build a simple 2d array but after the initialization I keep getting an error that the array is "undefined"
here's the code :
var board = [];
function initBoard(){
for (var i = 0; i < 8; i++){
board.push([]);
for (var j = 0 ;i < 8; i++){
board[j].push([]);
}
}
}
function checkSquare(x, y){
if (typeof(board[x][y]) === ""){
return false;
} else {
return true;
}
}
initBoard();
console.log(checkSquare(3, 3));
Here's the error : Cannot read property '3' of undefined`
You need not only take a look to the loops, but also to the check of the value of an item of the array. The comparison with the result of typeof with an empty string is always false, because there is no data type in Javascript Which is an empty string.
For comparing the value, you could check with the value directly with a Identity/strict equality operator ===. This checks the type of the left and right side and the value as well. For objects, it check if the object has the same reference.
function initBoard() {
var board = [];
for (var i = 0; i < 8; i++) {
board.push([]);
for (var j = 0; j < 8; j++) {
board[i].push('');
}
}
return board;
}
function checkSquare(x, y) {
if (board[x][y] === '') { // check if the item is an empty string
return false;
} else {
return true;
}
}
var board = initBoard();
console.log(checkSquare(3, 3));
There's a little mistale you've made while initialising. You've misplaced j with i. Try this:
var board = [];
function initBoard(){
for (var i = 0; i < 8; i++){
board.push([]);
for (var j = 0 ;j< i; j++){ //There was a mistake here
board[j].push([]);
}
}
}
function checkSquare(x, y){
if (typeof(board[x][y]) === ""){
return false;
} else {
return true;
}
}
initBoard();
console.log(checkSquare(3, 3));
var board = [];
function initBoard(){
for (var i = 0; i < 8; i++){
board.push([]);
for (var j = 0 ;j< i; j++){
board[j].push([]);
}
}
}
function checkSquare(x, y){
if (typeof(board[x][y]) === ""){
return false;
} else {
return true;
}
}
initBoard();
console.log(checkSquare(3, 3));
Two main things, you have a typo in your second loop, it should be based on j not i
and when you are trying to initialize the second array you can't use push because board[j] is undefined and push is a method of an array
var board = [];
function initBoard(){
for (var i = 0; i < 8; i++){
board.push([]);
for (var j = 0 ;j < 8; j++){
board[j] = [];
}
}
}
function checkSquare(x, y){
if (typeof(board[x][y]) === ""){
return false;
} else {
return true;
}
}
initBoard();
console.log(checkSquare(3, 3));
Related
Please i am trying to build a Sudoku solver in JavaScript but i face a problem when i get to the solve function, the recursive loop doesn't stop when the board is full. It executes till the end even after finding the solution. Please I'll be grateful if i can get some help. Here is what i tried doing:
class SudokuSolver {
// convert puzzle string to 2D array
boardParser(puzzleString) {
var board = [];
var i, j;
for (i = 0; i < 81; i += 9) {
var boardRow = [];
for (j = 0; j < 9; j++) {
boardRow.push(puzzleString.charAt(i + j));
}
board.push(boardRow)
}
// console.log(board);
return board;
}
// Look for empty space on board (empty space = ".")
// return [row, col] if empty space found
// return [-1,-1] if no empty space found (board is full)
getDot(board) {
var i, j;
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (board[i][j] == ".") {
return [i, j];
}
}
}
return [-1, -1];
}
checkRowPlacement(board, row, column, value) {
var i;
for (i = 0; i < 9; i++) {
if (board[row][i] == value) {
// console.log("row check false");
return {
valid: false
};
}
}
// console.log("row check true");
return {
valid: true
}
}
checkColPlacement(board, row, column, value) {
var i;
for (i = 0; i < 9; i++) {
if (board[i][column] == value) {
// console.log("col check false")
return {
valid: false
}
}
}
// console.log("col check true")
return {
valid: true
};
}
checkRegionPlacement(board, row, column, value) {
var i, j;
var regRow = Math.floor(row / 3) * 3;
var regCol = Math.floor(column / 3) * 3;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (board[regRow + i][regCol + j] == value) {
// console.log("reg check false")
return {
valid: false
}
}
}
}
// console.log("reg check true");
return {
valid: true
}
}
checkvalue(board, row, column, value) {
var rowCheck = this.checkRowPlacement(board, row, column, value).valid
var colCheck = this.checkColPlacement(board, row, column, value).valid
var regCheck = this.checkRegionPlacement(board, row, column, value).valid
// console.log(rowCheck, colCheck, regCheck);
if (rowCheck && colCheck && regCheck) {
// console.log(true)
return true;
}
// console.log(false)
return false;
}
// convert 2D array back to string
stringifyBoard(board) {
var string = ""
var i, j;
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
string += board[i][j];
}
}
// console.log(string);
return string;
}
// check for any more empty spaces
solved(board) {
var i, j;
if (this.getDot(board)[0] == -1) {
return true
}
return false
}
solve(puzzleString) {
var board = this.boardParser(puzzleString)
var emptySpot = this.getDot(board);
var row = emptySpot[0];
var column = emptySpot[1];
// full board condition
if (this.solved(board)) {
return puzzleString;
}
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
this.solve(boardString);
}
}
// if board is unsolvable return false
return false;
}
}
const input = '5..91372.3...8.5.9.9.25..8.68.47.23...95..46.7.4.....5.2.......4..8916..85.72...3';
console.log(new SudokuSolver().solve(input));
it returns false, but the puzzle string is valid and also when i console log in the full board condition it shows the solved string but doesn't return it.
So once the board is solved and if this.solved(board) returns true, you are returning the solved board. But this is only at the last level of recursion chain. You need to check at every level of recursion if this particular move reaches a solved board state. Hence, validate the result of the next level and if it returns a solved board, return the solved board from the current level too. I have made appropriate changes in the solve function-
solve(puzzleString) {
var board = this.boardParser(puzzleString)
var emptySpot = this.getDot(board);
var row = emptySpot[0];
var column = emptySpot[1];
// full board condition
if (this.solved(board)) {
return puzzleString;
}
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
var result = this.solve(boardString);
if(result !== false){
return result;
}
}
}
// if board is unsolvable return false
return false;
}
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
if(this.solve(boardString)) return true; //I've a modification here
}
}
You didn't write any code to stop the function when the solution is found.
Here is my solution:
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
var sol = this.solve(boardString); // change
if (sol) return sol // change
}
}
I have done a similar one in python a while ago.
Check it here if you are interested: https://onlinegdb.com/SJt2PQrjP
So I mede the prime number generator in JavaScript:
function prime(from, to) {
for (var i = from; i <= to; i++) {
var IsPrime = false;
for (var j = from; j < i; j++) {
if (i % j == 0) {
IsPrime = true;
}
}
if (IsPrime == false) {
console.log([i]);
}
}
}
prime(2, 9999);
But the output looks like this...
[2]
[3]
[5]
[7]
[11]
...
...and I want it to look like this:
[2,3,5,7,11...]
can someone help me?
thanks for your ideas;-)
function prime(from, to) {
var result = []; // creating a variable for accumulating
for (var i = from; i <= to; i++) {
var IsPrime = false;
for (var j = from; j < i; j++) {
if (i % j == 0) {
IsPrime = true;
}
}
if (IsPrime == false) {
// console.log([i]);
result.push(i); // adding value
}
}
console.log(result) // console.log result
return result // returning for further usage
}
var a = prime(2, 9999); // put result into a variable
console.log(a); // console.log again for example
You're logging inside your loop. instead, push the results into an array, and just log the array at the end
function prime(from, to) {
var primearray = [];
for (var i = from; i <= to; i++) {
var IsPrime = false;
for (var j = from; j < i; j++) {
if (i % j == 0) {
IsPrime = true;
}
}
if (IsPrime == false) {
primearray.push(i);
}
}
console.log(primearray)
}
prime(2, 9999);
That's because you are logging each element separately. If you would like to have the output as an array - you can create an empty array and .push() elements to it.
See the example below.
function prime(from, to) {
let primeArray = [];
for (var i = from; i <= to; i++) {
var IsPrime = false;
for (var j = from; j < i; j++) {
if (i % j == 0) {
IsPrime = true;
}
}
if (IsPrime == false) {
primeArray.push([i]);
}
}
console.log(primeArray)
}
prime(2, 9999);
Cheers.
You can just add numbers to array:
function prime(from, to) {
var arr = [];
for (var i = from; i <= to; i++) {
var IsPrime = false;
for (var j = from; j < i; j++) {
if (i % j == 0) {
IsPrime = true;
}
}
if (IsPrime == false) {
arr.push(i);
}
if(i === to) {
return arr;
}
}
}
console.log(prime(2, 10));
Try this below:
function prime(from, to) {
let output = []
for (var i = from; i <= to; i++) {
var IsPrime = false;
for (var j = from; j < i; j++) {
if (i % j == 0) {
IsPrime = true;
}
}
if (IsPrime == false) {
output.push([i]);
}
}
print(output)
}
prime(2, 9999);
I'm new to javascript and I'm working on an assignment to create a function that calculates the average using the numbers in an array. If the array is [], it should return null.
I have the following code so far but it keeps returning NaN instead of null, can someone please explain this to me? Thanks in advance.
function mean(arr) {
if (arr == []) {
return null;
} else {
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return round(sum / arr.length);
}
}
console.log(mean([6,2,3,3,110,6,1,0,5])); //returns 4
console.log(mean([])); //currently returning NaN, instead of null
Here you go. Just change arr == [] to arr.length == 0.
function mean(arr) {
if (arr.length == 0) {
return null;
} else {
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return Math.round(sum / arr.length);
}
}
console.log(mean([6,2,3,3,110,6,1,0,5])); //returns 4
console.log(mean([])); //currently returning NaN, instead of null
Check the length of the array using arr.length ===0
function mean(arr) {
if (arr.length === 0) {
return null;
} else {
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return round(sum / arr.length);
}
}
console.log(mean([]));
Added additional condition to check if the variable is not an array to avoid runtime exception.
function mean(arr) {
If (arr.constructor != Array) return null;
if (arr.length == 0) {
return null;
} else {
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return Math.round(sum / arr.length);
}
}
var array = [[2,3,4],[4,5,6],[2,3,9],[7,8,1]];
var number = 3;
If I have this nested array and this variable how do I return the index of the sub-arrays where the number is present. So the final result should be 1 and 3.
Try:
array.reduce((acc, subArr, i) => {
if (!subArr.includes(number)) {
acc.push(i);
}
return acc;
}, [])
The solution using Array.prototype.forEach() and Array.prototype.indexOf() functions:
var arr = [[2,3,4],[4,5,6],[2,3,9],[7,8,1]],
number = 3,
result = [];
arr.forEach(function(v,i){
if (v.indexOf(number) === -1) result.push(i);
});
console.log(result);
function X(a){
var r = [];
for(var i = o ; i < a.length; i++)
for(var j = o ; j < a[i].length; i++)
if(a[i][j] === number)
r.push(i);
return r;
}
i think this should do it. i have just written it here so might have some syntax errors
Since the question is super inconsistent, if you want the index of the subarrays that do have the number, do this:
var foundIndices = [];
for(var y = 0;y < array.length; y++) {
for(var x = 0;x < array[y].length; x++) {
if(array[y][x] == number) {
foundIndices[foundIndices.length] = y;
}
}
}
Otherwise, do this:
var foundIndices = [];
var found = false;
for(var y = 0;y < array.length; y++) {
found = false;
for(var x = 0;x < array[y].length; x++) {
if(array[y][x] == number) {
found = true;
}
}
if(found == false) {
foundIndices[foundIndices.length] = y;
}
}
Write a Boolean function named isPrime which takes an integer as an argument and returns true if the argument is a prime number of false otherwise. Generate 100 random numbers and display the results of checking each one for primality.
This is supposed to output the random numbers that are prime (after the true or false check) but I am getting the results of 2 sets of numbers in order.
Here is my code:
var arr = []
while(arr.length < 100){
var randomnumber=Math.ceil(Math.random()*100)
var found=false;
for(var i=0;i<arr.length;i++){
if(arr[i]==randomnumber){found=true;break}
}
if(!found)arr[arr.length]=randomnumber;
}
console.log(arr);
for(i = 0; i < 100; i++){
if(isPrime(i)) console.log(i);
}
function isPrime(num) {
if(num < 2) return false;
for (var i = 2; i < num; i++) {
if(num%i==0)
return false;
}
return true;
}
You need to check for primality of arr[i] instead of i:
for(i = 0; i < 100; i++){
if(isPrime(arr[i])) console.log(arr[i]);
}
function isPrime(value) {
for(var i = 2; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
}
function myFunction() {
for(var i = 0; i < 100; i++) {
$('#demo').append('<div>'+i+'*****'+isPrime(i)+'</div>');
}
}
try it in an html page and dont forget to add jquery
The below code part, you are trying to check the numbers from 0 to 100
for(i = 0; i < 100; i++){
if(isPrime(i)) console.log(i);
}
But you should check the arr array one by one
for(i = 0; i < 100; i++){
if(isPrime(arr[i])) console.log(arr[i]);
}
Using an object to store the numbers let's you avoid the loop to check for duplicates and moving the check for isPrime () let's you skip the second loop. (Your issue was, as #Andrea pointed out, not passing arr [i] to isPrime)
var myRandObj = {};
var randomNumber = 0;
for (var i = 0; i < 100; i++) {
do {
randomNumber = Math.ceil(Math.random() * 100);
} while (typeof myRandObj[randomNumber] !== 'undefined');
myRandObj[randomNumber] = 0;
if (isPrime (randomNumber))
console.log (randomNumber);
}
console.log(arr) is printing the entire array to the console. Remove that line to debug further.
var arr = []
for(x = 0; x < 100; x++){
arr[x] = Math.ceil(Math.random()*100)
}
for(i = 0; i < 100; i++){
if(isPrime(arr[i])) console.log(arr[i]);
}
function isPrime(num) {
if(num < 2) return false;
for (var i = 2; i < num; i++) {
if(num%i==0)
return false;
}
return true;
}