Skip to content

Commit

Permalink
Take advantage of Structure.contents
Browse files Browse the repository at this point in the history
  • Loading branch information
melusc committed Mar 11, 2022
1 parent bd70c32 commit 096dab8
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 16 deletions.
10 changes: 1 addition & 9 deletions src/plugins/hidden-pairs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,15 @@ const genericHiddenPairsSolver: VisitorFn = (structure, sudoku) => {
// This is a lot better than comparing arrays of indexes
const summary = new Map<number, bigint>();

// If there is `content`, the hidden pairs can't have
// that number anyway, so just keep track of them and ignore
// candidates that already exist as `content`
const foundContent = new Set<number>();

for (const [index, {content, candidates}] of structure.entries()) {
const pow = 1n << BigInt(index);

if (content === undefined) {
for (const candidate of candidates) {
if (!foundContent.has(candidate)) {
if (structure.contents[candidate] === 0) {
summary.set(candidate, (summary.get(candidate) ?? 0n) | pow);
}
}
} else {
summary.delete(content);
foundContent.add(content);
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/plugins/remove-by-content.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {makeVisitor} from './shared.js';

export const removeByContent = makeVisitor((structure, sudoku) => {
for (const {content} of structure) {
if (content !== undefined) {
for (const cell of structure) {
sudoku.removeCandidate(cell, content);
const contents = Object.keys(structure.contents);

for (const cell of structure) {
if (cell.content === undefined) {
for (const content of contents) {
sudoku.removeCandidate(cell, Number(content));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/shared.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {Sudoku, ReadonlyCells} from '../sudoku.js';
import type {Sudoku, Structure} from '../sudoku.js';

// From https://stackoverflow.com/q/43122082/13249743
const bitCount32 = (n: bigint): bigint => {
Expand Down Expand Up @@ -37,7 +37,7 @@ export const bitIndex = (n: bigint): number => {
return n.toString(2).length - 1;
};

export type VisitorFn = (structure: ReadonlyCells, sudoku: Sudoku) => void;
export type VisitorFn = (structure: Structure, sudoku: Sudoku) => void;
export const makeVisitor
= (cb: VisitorFn): ((sudoku: Sudoku) => void) =>
(sudoku: Sudoku): void => {
Expand Down
7 changes: 6 additions & 1 deletion src/sudoku.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type Cell = {
};
export type ReadonlyCells = readonly Cell[];

type Structure = ReadonlyCells & {contents: Record<number, number>};
export type Structure = ReadonlyCells & {contents: Record<number, number>};

type PrefilledSudoku = ReadonlyArray<
undefined | ReadonlyArray<string | number | readonly number[] | undefined>
Expand Down Expand Up @@ -49,6 +49,11 @@ const makeContentsRecord = (): Record<number, number> =>
throw new Error(`${key} , value < 0`);
}

if (value === 0) {
Reflect.deleteProperty(target, key);
return true;
}

return Reflect.set(target, key, value);
},
},
Expand Down
39 changes: 39 additions & 0 deletions test/plugins/hidden-pairs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,42 @@ test('hiddenPairs should find an incomplete hidden pair', t => {
],
);
});

test('hiddenPairs should find the hidden pairs ("3", "4", "0") by ignoring "5".', t => {
/*
It might see (3, 4, 5, 0) in #1..3, but it should know
that 5 already is a number in the structure and
should therefore ignore it, leaving (3, 4, 0)
*/

const s = Sudoku.fromPrefilled(
[
_,
_,
_,
_,
[
[3, 4, 5, 6, 8, 0], // #1
[1, 5, 7, 8],
5,
[1, 3, 4, 5, 7, 8, 0], // #2
[5, 7, 8],
[2, 3, 4, 5, 6, 0], // #3
[1, 6, 7, 8],
[1, 6, 7, 8],
[2, 5, 6, 8],
],
],
9,
);

hiddenPairs(s);

const wantedSet = new Set([3, 4, 0]);

t.deepEqual(s.getCell(4 * 9).candidates, wantedSet);

t.deepEqual(s.getCell(4 * 9 + 3).candidates, wantedSet);

t.deepEqual(s.getCell(4 * 9 + 5).candidates, wantedSet);
});

0 comments on commit 096dab8

Please sign in to comment.