feat: expand sudoku analysis and interoperability
This commit is contained in:
@@ -38,6 +38,28 @@ describe("logical solver", () => {
|
||||
expect(result.steps).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("does not apply positive cage reductions to a false cage", () => {
|
||||
const result = solveLogically({
|
||||
version: 1,
|
||||
size: 4,
|
||||
givens: Array<number>(16).fill(0),
|
||||
regions: classicRegions(4),
|
||||
constraints: [
|
||||
{
|
||||
type: "killer-cage",
|
||||
cells: [0, 1],
|
||||
sum: 3,
|
||||
noRepeat: false,
|
||||
negated: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(result.status).toBe("stuck");
|
||||
expect(result.steps).toEqual([]);
|
||||
expect(result.candidates[0]).toEqual([1, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it("returns bounded killer combinations", () => {
|
||||
expect(
|
||||
killerDigitCombinations({ size: 9, count: 2, sum: 10 }).combinations,
|
||||
|
||||
@@ -196,6 +196,35 @@ describe("variant generator", () => {
|
||||
expect(generated.puzzle.rules).not.toMatch(/Kropki|negative/i);
|
||||
});
|
||||
|
||||
it("mines deterministically for a requested practice technique", () => {
|
||||
const options = {
|
||||
variant: "classic",
|
||||
size: 9,
|
||||
seed: "mine-practice",
|
||||
targetDifficulty: "hard",
|
||||
requiredTechnique: "naked-pair",
|
||||
maxTechniqueAttempts: 6,
|
||||
maxChecks: 72,
|
||||
} as const;
|
||||
const generated = generateVariant(options);
|
||||
expect(generated.requestedTechnique).toBe("naked-pair");
|
||||
expect(generated.generationAttempts).toBe(4);
|
||||
expect(generated.difficulty.techniqueCounts["naked-pair"]).toBeGreaterThan(
|
||||
0,
|
||||
);
|
||||
expect(generateVariant(options)).toEqual(generated);
|
||||
});
|
||||
|
||||
it("keeps Killer-cage practice tied to the Killer generator", () => {
|
||||
expect(() =>
|
||||
generateVariant({
|
||||
variant: "classic",
|
||||
size: 4,
|
||||
requiredTechnique: "killer-cage",
|
||||
}),
|
||||
).toThrow(/requires the Killer generator/i);
|
||||
});
|
||||
|
||||
it("keeps the public variant ID type exhaustive", () => {
|
||||
const ids: GeneratorVariant[] = GENERATOR_VARIANTS.map(({ id }) => id);
|
||||
expect(new Set(ids).size).toBe(GENERATOR_VARIANTS.length);
|
||||
|
||||
Reference in New Issue
Block a user