Published
Edited
Jan 23, 2020
16 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function* solve() {
const state = parseInput();
const size = state.length;

function* solveFromIndex(index) {
if (index === size ** 2) {
return true;
}
const i = Math.floor(index / size);
const j = index % size;
if (state[i][j]) {
return (yield* solveFromIndex(index + 1));
} else {
for (let k = 1; k <= size; k += 1) {
state[i][j] = k;
yield state;
if (isValid(state) && (yield* solveFromIndex(index + 1))) {
return true;
}
}
state[i][j] = null;
return false;
}
}
yield* solveFromIndex(0);
}
Insert cell
function isValid(state) {
const size = state.length;
const boxSize = Math.sqrt(size);
for (let i = 0; i < size; i += 1) {
const row = [];
const column = [];
const box = [];
const i0 = (i % boxSize) * boxSize;
const j0 = Math.floor(i / boxSize) * boxSize;
for (let j = 0; j < size; j += 1) {
row.push(state[i][j]);
column.push(state[j][i]);
const i1 = (j % boxSize);
const j1 = Math.floor(j / boxSize);
box.push(state[i0 + i1][j0 + j1]);
}
if (!(isUnique(row) && isUnique(column) && isUnique(box))) {
return false;
}
}
return true;
}
Insert cell
function isUnique(group) {
const values = group.filter(value => value !== null);
return values.length === new Set(values).size;
}
Insert cell
function parseInput() {
const rows = input.trim().split('\n');
return rows.map(row => row.split('').map(digit => parseInt(digit) || null));
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more