I wrote a sudoku solver in Javascript for https://leetcode.com/problems/sudoku-solver/solution/. Whenever I use the same code in an IDE outside of leetcode, it solves the sudoku board fine. However, when I submit it as an answer in leetcode, it always returns a the default board parameter passed in to the function. Can anyone figure out why?
Note: The leetcode problem says to solve the board in place and not to return anything.
Error: imgur.com/a/63v7sOu
/**
* #param {character[][]} board
* #return {void} Do not return anything, modify board in-place instead.
*/
var solveSudoku = function(board) {
function check(y, x, n, board){
// Search column for n
for (let i = 0; i < 9; i++){
if (board[y][i] == n) return false;
}
// Search row for n
for (let i = 0; i < 9; i++){
if (board[i][x] == n) return false;
}
const row = Math.floor(x / 3) * 3;
const col = Math.floor(y / 3) * 3;
for (let i = 0; i < 3; i++){
for (let j = 0; j < 3; j++){
if (board[col+i][row+j] == n) return false;
}
}
return true;
}
function solve(board){
for (let y = 0; y < 9; y++){
for (let x = 0; x < 9; x++){
if (board[y][x] === "."){
for (let n = 1; n < 10; n++){
if(check(y, x, n, board)){
board[y][x] = n.toString();
solve(board);
board[y][x] = ".";
}
}
return;
}
}
}
}
solve(board)
}
solveSudoku doesn't do anything, it only defines two functions. Call solve(board) in the function body.
Related
I've implemented Conway's game of life in p5.js.
I have a function which counts the number of alive neighbours of a given cell, it appears from the tests I did that it works perfectly. That being said I'm having unexpected behaviour when it comes to simulating : it's not following the correct patterns. I start here with 3 aligned squares (a blinker) and it's supposed to rotate but for some reason they just all die.
Wikipedia shows how a blinker should behave : https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Examples_of_patterns
You can copy paste the source below into https://editor.p5js.org/ and see for yourself.
I'm suspecting the issue has got something to do with copying of the board (matrice of cells), because an update has to be simultaneous for all cells, hence we keep in memory the previous board and update the current board based on the previous board.
Source :
//size of cell in pixels.
const size = 20;
const canvasWidth = 400;
const canvasHeight = 400;
const n = canvasWidth / size;
const m = canvasHeight / size;
class Cell {
constructor(status, position) {
this.status = status;
this.position = position;
}
}
let board = [];
function setup() {
//initialise matrix.
for(let i=0; i < m; i++) {
board[i] = new Array(n);
}
//fill matrix of cells.
for(let i=0; i < m; i++ ) {
for(let j=0; j < n; j++ ) {
board[i][j] = new Cell(false, [i*size, j*size]);
}
}
console.log("start", floor(m /2), floor(n / 2))
//[x, y] positions.
board[floor(m /2)][floor(n / 2)].status = true;
board[floor(m /2)+1][floor(n / 2)].status = true;
board[floor(m /2)+2][floor(n / 2)].status = true;
createCanvas(canvasWidth, canvasHeight);
frameRate( 1 )
}
//I'm 99.99% sure this function works, all the tests shows it does.
function updateCell(i, j, previousBoard) {
let count = 0;
//check neighbourgh cells.
for(let k=-1; k < 2; k++) {
for(let p=-1; p < 2; p++) {
if( !(i + k < 0 || j + p < 0 || j + p >= n || i + k >= m) ) {
if(k != 0 || p != 0) {
if(previousBoard[i+k][j+p].status === true) {
count++;
}
}
}
}
}
console.log(count)
if((previousBoard[i][j].status === true) && (count < 2 || count > 3)) {
//console.log("false", i, j, count)
board[i][j].status = false;
} else if((count === 3) && (previousBoard[i][j].status === false)) { //if dead but 3 alive neighbours.
//alive
console.log("true", i, j, count)
board[i][j].status = true;
} else if((previousBoard[i][j].status === true) && (count === 2 || count === 3)) {
console.log("true", i, j, count)
board[i][j].status = true;
}
}
function copyMatrix() {
let newMatrix = []
for(let i=0; i < m; i++) {
//console.log(board[i])
newMatrix[i] = board[i].slice()
}
//console.log(newMatrix)
return newMatrix
}
function draw() {
background(220);
//draw rectangles.
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
if (board[i][j].status === true) {
fill('black');
} else {
fill('white');
}
rect(board[i][j].position[0], board[i][j].position[1], size, size);
}
}
//slice copies previous array into a new reference, previousBoard and board are
//now independent.
let previousBoard = copyMatrix();
//updateCell(11, 9, previousBoard) //uncommenting this line creates weird results...
//console.log(previousBoard)
//update all cells based on previousBoard. (we'll modify board based on previous)
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
updateCell(i, j, previousBoard);
}
}
}
<html>
<head>
<Title>Gordon's Game of Life</Title>
<script src = "p5.js"></script>
<script src = "sketch.js"></script>
</head>
<body>
<h1>Gordon's Game of Life</h1>
</body>
</html>
The issue is that copyMatrix needs to do a deep copy.
Change copy matrix to this:
function copyMatrix() {
let newMatrix = []
for(let i=0; i < m; i++) {
newMatrix[i] = [];
for (let j=0;j< n;j++){
newMatrix[i][j] = new Cell(board[i][j].status, board[i][j].position);
}
}
return newMatrix
}
Here is your code with the copyMatrix change and an added glider to help demonstrate behavior.
//size of cell in pixels.
const size = 20;
const canvasWidth = 400;
const canvasHeight = 400;
const n = canvasWidth / size;
const m = canvasHeight / size;
class Cell {
constructor(status, position) {
this.status = status;
this.position = position;
}
}
let board = [];
function setup() {
//initialise matrix.
for(let i=0; i < m; i++) {
board[i] = new Array(n);
}
//fill matrix of cells.
for(let i=0; i < m; i++ ) {
for(let j=0; j < n; j++ ) {
board[i][j] = new Cell(false, [i*size, j*size]);
}
}
board[floor(m /2)][floor(n / 2)].status = true;
board[floor(m /2)+1][floor(n / 2)].status = true;
board[floor(m /2)+2][floor(n / 2)].status = true;
// glider
board[0][0].status = true;
board[0][2].status = true;
board[1][1].status = true;
board[1][2].status = true;
board[2][1].status = true;
createCanvas(canvasWidth, canvasHeight);
frameRate( 1 )
}
function updateCell(i, j, previousBoard) {
let count = 0;
//check neighbourgh cells.
for(let k=-1; k < 2; k++) {
for(let p=-1; p < 2; p++) {
if( !(i + k < 0 || j + p < 0 || j + p >= n || i + k >= m) ) {
if(k != 0 || p != 0) {
if(previousBoard[i+k][j+p].status === true) {
count++;
}
}
}
}
}
if((previousBoard[i][j].status) && (count < 2 || count > 3)) {
board[i][j].status = false;
} else if((count === 3) && (!previousBoard[i][j].status)) { //if dead but 3 alive neighbours.
board[i][j].status = true;
} else if((previousBoard[i][j].status) && (count === 2 || count === 3)) {
board[i][j].status = true;
}
}
function copyMatrix() {
let newMatrix = []
for(let i=0; i < m; i++) {
newMatrix[i] = [];
for (let j=0;j< n;j++){
newMatrix[i][j] = new Cell(board[i][j].status, board[i][j].position);
}
}
return newMatrix
}
function draw() {
background(220);
//draw rectangles.
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
if (board[i][j].status === true) {
fill('black');
} else {
fill('white');
}
rect(board[i][j].position[0], board[i][j].position[1], size, size);
}
}
let previousBoard = copyMatrix();
//updateCell(11, 9, previousBoard) //uncommenting this line creates weird results...
//console.log(previousBoard)
//update all cells based on previousBoard. (we'll modify board based on previous)
for(let i=0; i < m; i++) {
for(let j=0; j < n; j++) {
updateCell(i, j, previousBoard);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>
With the glider this setup demonstrates all three possible patterns. We start with a moving spaceship glider and an oscillator and when the glider runs into the oscillator we have a few iterations that break both patterns and then it settles down into a 2x2 still life.
Ok so i tried to make conway's game of life in p5.js and i am stuck in some wierd bug .
function make2DArray(cols, rows) {
let arr = new Array(cols);
for (let i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
function countNeighbors(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = x + i;
let row = y + i;
if (grid[col][row] === undefined){
sum += grid[col][row];
}
}
}
sum-=grid[x][y]
return sum;
}
let grid;
let next;
let cols;
let rows;
let resolution = 20;
let fr = 15;
function setup() {
createCanvas(600, 400);
frameRate(fr);
cols = width / resolution;
rows = height / resolution;
next = make2DArray(cols, rows);
grid = make2DArray(cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j] = floor(random(2));
}
}
}
function draw() {
background(0);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * resolution;
let y = j * resolution;
if (grid[i][j] == 1) {
fill(0);
stroke(150);
rect(x, y, resolution - 1, resolution - 1);
} else {
fill(255);
stroke(150);
rect(x, y, resolution - 1, resolution - 1);
}
}
}
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let state = grid[i][j];
let neighbors = countNeighbors(grid, i, j);
if (state == 0 && neighbors == 3) {
next[i][j] = 1;
} else if (state == 1 && (neighbors < 2 || neighbors > 3)) {
next[i][j] = 0;
} else {
next[i][j] = state;
}
}
}
grid = next;
}
Soo basically i have function countNeighbors and i think that bug is in there , i tried checking if col and row are i boundaries of array
like this
if (col>-1 && col <grid.length && row>-1 && row < grid[0].length){
//increase sum
}
but its even worse. I am new to js so i figured out that if for example
let x=new Array(10);
//and then when i try this
console.log(c[-1])
//it should give undefined
but program still wont work :(
Thanks!
With a few changes you can make it work:
1) Replace let row = y + i; by let row = y + j; That typo was making most of the counts off.
2) Replace the condition
if (grid[col][row] === undefined){
by
if (0 <= col && col < cols && 0 <= row && row < rows){
The problem with your original condition is that if grid[col] is undefined then grid[col][row] is undefined[row], which doesn't make sense.
3) For consistency sake, add a semicolon to the end of sum-=grid[x][y]
4) Finally, so as to not create an unintended alias, you need to replace grid = next by something like:
for(let i = 0; i < grid.length; i++){
grid[i] = next[i].slice();
}
Alternatively, make next a variable which is local to draw() and place the line let next = make2DArray(cols, rows); to the beginning of draw().
I was looking for an answer for a question from Project Euler and I found one here
http://www.mathblog.dk/triangle-number-with-more-than-500-divisors/
int number = 0;
int i = 1;
while(NumberOfDivisors(number) < 500){
number += i;
i++;
}
private int NumberOfDivisors(int number) {
int nod = 0;
int sqrt = (int) Math.Sqrt(number);
for(int i = 1; i<= sqrt; i++){
if(number % i == 0){
nod += 2;
}
}
//Correction if the number is a perfect square
if (sqrt * sqrt == number) {
nod--;
}
return nod;
}
So I tried to implement the same solution in Javascript but it doesn't give me the same result.
var number = 0;
var i = 1;
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.sqrt(num);
for (i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
I tested the other code in C# and it gives the right solution. I was wondering if I made a mistake or whether they work differently in some aspect I'm unaware of.
The problem is that you are testing non-triangle numbers because you forgot one important thing ... scope ...
for (i = 1; i <= sqr; i++) {
screws your (global) value of i ...
see in c# you have
for(int i = 1; i<= sqrt; i++){
^^^
give javascript the same courtesy and try
for (var i = 1; i <= sqr; i++) {
^^^
you should also get the square root as an integer, otherwise you'll be one off in most counts
var sqr = Math.floor(Math.sqrt(num));
i.e.
var number = 0;
var i = 1;
console.time('took');
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.timeEnd('took');
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.floor(Math.sqrt(num));
for (var i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
(added some timing info for fun)
I'm trying to write a function in JavaScript to generate an array of permutations of a given array by porting the code in the Python documentation for itertools.permutations. (I am aware that the actual function is written in C) This is what I have, and it outputs an array with the correct length - n!/(n-r)!, n being the length of the array - but each element is just the original array, not rearranged. I'd appreciate a fresh pair of eyes on my code, as I'm stumped:
function permutations(array, r) {
if (r === undefined) r = array.length;
if (r > array.length) return;
var indices = range(array.length);
var cycles = range(array.length, array.length - r, -1);
var result = [[]];
for (var i = 0; i < r; i++) {
result[0].push(array[i]);
}
while (1) {
var exhausted = true;
for (var i = r - 1; i >= 0; i--) {
cycles[i] -= 1;
if (cycles[i] == 0) {
indices = indices.slice(0, i).concat(
indices.slice(i + 1)
).concat([indices[i]]);
cycles[i] = array.length - i;
}
else {
var j = cycles[i];
swap(indices, i, indices.length - j);
var p = [];
for (var i = 0; i < r; i++) {
p.push(array[i]);
}
result.push(p);
exhausted = false;
break;
}
}
if (exhausted) break;
}
return result;
}
The python code has (near the bottom):
yield tuple(pool[i] for i in indices[:r])
You translated that to:
for (var i = 0; i < r; i++) {
p.push(array[i]);
}
result.push(p);
But it should be:
for (var i = 0; i < r; i++) {
p.push(array[indices[i]]);
}
result.push(p);
Without that, indices is never used, which should be a clue.
So, I need to fill a bi-dimensional array in JavaScript and I'm doing it the following way:
var i = 0, j = 0;
for (i = 0; i < roomWidth / tileWidth; i += 1) {
roomBuffer[i] = [];
}
for (i = 0; roomWidth / tileWidth; i += 1) {
for (j = 0; j < roomHeight / tileHeight; j += 1) {
roomBuffer[i][j] = 1;
}
}
alert("Hello world");
The problem is that it not only doesn't work but any code that comes after it, it's not executed. In this case the alert("Hello world");. What am I doing wrong guys?
change
for (i = 0; roomWidth / tileWidth; i += 1) {
to
for (i = 0; i < roomWidth / tileWidth; i += 1) {
You don't need to declare i and j before the loops. If their existence is solely for the loops, they are better off as local variables. Also, you can combine loops.
Also, what #Yuriy Zubarev said is right. The middle statement in the for-loop is a condition that must hold true throughout the loop.
for (var i = 0; i < roomWidth / tileWidth; i++) {
roomBuffer[i] = [];
for (var j = 0; j < roomHeight / tileHeight; j++) {
roomBuffer[i][j] = 1;
}
}
alert("Hello world");
Have a look at this fiddle.
change your
for (i = 0; roomWidth / tileWidth; i += 1)
to
for (i = 0; i < roomWidth / tileWidth; i += 1)
You can simplify your code by using a small helper function
// create an array of length len filled with value
fill = function(len, value) {
for (var a = []; len-- > 0; a.push(value));
return a;
}
Your code:
size = roomWidth / tileWidth
roomBuffer = fill(size, fill(size, 1))