diff --git a/.eslintrc.json b/.eslintrc.json index 89cad21..d1bc0a4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,16 +3,27 @@ "es2021": true, "node": true }, - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], "overrides": [], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, - "plugins": ["@typescript-eslint"], + "plugins": [ + "@typescript-eslint" + ], "rules": { - "indent": ["error", 4], - "quotes": ["error", "double"] + "indent": [ + "error", + 2 + ], + "quotes": [ + "error", + "double" + ] } -} +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2c76fff..e1f0a39 100644 --- a/.gitignore +++ b/.gitignore @@ -134,4 +134,7 @@ dist data # AstrOGD Userdata directory -userdata \ No newline at end of file +userdata + +# output +output.cnf diff --git a/.prettierrc.json b/.prettierrc.json index 5234a6c..840a57d 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,6 +1,6 @@ { "printWidth": 150, - "tabWidth": 4, + "tabWidth": 2, "semi": true, "singleQuote": false, "quoteProps": "consistent", diff --git a/generateRules.ts b/generateRules.ts new file mode 100644 index 0000000..c992c9c --- /dev/null +++ b/generateRules.ts @@ -0,0 +1,15 @@ +import generateRules, { getLength } from "./src/rules"; +import fs from "fs"; +import { v } from "./src/util"; + +const constValues: number[] = []; +const rules = generateRules(constValues); + +const output = fs.createWriteStream("output.cnf"); +output.write(`p cnf ${v(9, 9, 9)} ${getLength(constValues)}\n`); + +for (const rule of rules) { + output.write(rule + "\n"); +} + +output.end(); diff --git a/index.ts b/index.ts deleted file mode 100644 index 940a3ff..0000000 --- a/index.ts +++ /dev/null @@ -1 +0,0 @@ -console.log("Hello world!"); diff --git a/package.json b/package.json index f0ae379..0569a32 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@tu-darmstadt/aupl-ss24-sudoku-solver", "version": "1.0.0-dev.1", "description": "A tool converting a given sudoku into DIMACS CNF to be solved with a SAT solver, and reverting the solution from the SAT solver back into an easy readable sudoku visualitsation", - "main": "dist/index.js", + "main": "dist/generateRules.js", "types": "dist/types/", "directories": { "bin": "dist/bin/" diff --git a/src/rules/allValuesBlock.ts b/src/rules/allValuesBlock.ts new file mode 100644 index 0000000..c673597 --- /dev/null +++ b/src/rules/allValuesBlock.ts @@ -0,0 +1,29 @@ +import { v } from "../util"; + +export default function* allValuesBlock(): Generator { + let count = 0; + for (const x of [1, 4, 7]) { + for (const y of [1, 4, 7]) { + for (let w = 1; w < 10; w++) { + yield [ + v(x, y, w), + v(x, y + 1, w), + v(x, y + 2, w), + v(x + 1, y, w), + v(x + 1, y + 1, w), + v(x + 1, y + 2, w), + v(x + 2, y, w), + v(x + 2, y + 1, w), + v(x + 2, y + 2, w), + ]; + count++; + } + } + } + + console.log("allValuesBlock: " + count); + + return null; +} + +export const length = 3 * 3 * 9; diff --git a/src/rules/allValuesColumn.ts b/src/rules/allValuesColumn.ts new file mode 100644 index 0000000..a43b9ad --- /dev/null +++ b/src/rules/allValuesColumn.ts @@ -0,0 +1,17 @@ +import { v } from "../util"; + +export default function* allValuesColumn(): Generator { + let count = 0; + for (let x = 1; x < 10; x++) { + for (let w = 1; w < 10; w++) { + yield [v(x, 1, w), v(x, 2, w), v(x, 3, w), v(x, 4, w), v(x, 5, w), v(x, 6, w), v(x, 7, w), v(x, 8, w), v(x, 9, w)]; + count++; + } + } + + console.log("allValuesColumn: " + count); + + return null; +} + +export const length = 9 * 9; diff --git a/src/rules/allValuesRow.ts b/src/rules/allValuesRow.ts new file mode 100644 index 0000000..6707fee --- /dev/null +++ b/src/rules/allValuesRow.ts @@ -0,0 +1,17 @@ +import { v } from "../util"; + +export default function* allValuesRow(): Generator { + let count = 0; + for (let y = 1; y < 10; y++) { + for (let w = 1; w < 10; w++) { + yield [v(1, y, w), v(2, y, w), v(3, y, w), v(4, y, w), v(5, y, w), v(6, y, w), v(7, y, w), v(8, y, w), v(9, y, w)]; + count++; + } + } + + console.log("allValuesRow: " + count); + + return null; +} + +export const length = 9 * 9; diff --git a/src/rules/atLeastOneValue.ts b/src/rules/atLeastOneValue.ts new file mode 100644 index 0000000..9726c02 --- /dev/null +++ b/src/rules/atLeastOneValue.ts @@ -0,0 +1,17 @@ +import { v } from "../util"; + +export default function* atLeastOneValue(): Generator { + let count = 0; + for (let x = 1; x < 10; x++) { + for (let y = 1; y < 10; y++) { + yield [v(x, y, 1), v(x, y, 2), v(x, y, 3), v(x, y, 4), v(x, y, 5), v(x, y, 6), v(x, y, 7), v(x, y, 8), v(x, y, 9)]; + count++; + } + } + + console.log("atLeastOneValue: " + count); + + return null; +} + +export const length = 9 * 9; diff --git a/src/rules/fixedValues.ts b/src/rules/fixedValues.ts new file mode 100644 index 0000000..62fea9b --- /dev/null +++ b/src/rules/fixedValues.ts @@ -0,0 +1,15 @@ +export default function* fixedValues(values: number[]): Generator { + let count = 0; + for (const value of values) { + yield [value]; + count++; + } + + console.log("fixedValues: " + count); + + return null; +} + +export function getLength(values: number[]): number { + return values.length; +} diff --git a/src/rules/index.ts b/src/rules/index.ts new file mode 100644 index 0000000..d59872f --- /dev/null +++ b/src/rules/index.ts @@ -0,0 +1,24 @@ +import allValuesBlock, { length as l1 } from "./allValuesBlock"; +import allValuesColumn, { length as l2 } from "./allValuesColumn"; +import allValuesRow, { length as l3 } from "./allValuesRow"; +import atLeastOneValue, { length as l4 } from "./atLeastOneValue"; +import fixedValuesHandler, { getLength as getL5 } from "./fixedValues"; +import maxOneValue, { length as l6 } from "./maxOneValue"; + +export default function* generateRules(fixedValues: number[]): Generator { + const generators = [allValuesBlock(), allValuesColumn(), allValuesRow(), atLeastOneValue(), maxOneValue(), fixedValuesHandler(fixedValues)]; + + for (const generator of generators) { + let rule = generator.next().value; + while (rule !== null) { + yield rule.join(" ") + " 0"; + rule = generator.next().value; + } + } + + return null; +} + +export function getLength(fixedValues: number[]): number { + return l1 + l2 + l3 + l4 + getL5(fixedValues) + l6; +} diff --git a/src/rules/maxOneValue.ts b/src/rules/maxOneValue.ts new file mode 100644 index 0000000..94769da --- /dev/null +++ b/src/rules/maxOneValue.ts @@ -0,0 +1,21 @@ +import { v } from "../util"; + +export default function* maxOneValue(): Generator { + let count = 0; + for (let x = 1; x < 10; x++) { + for (let y = 1; y < 10; y++) { + for (let w = 1; w < 9; w++) { + for (let w2 = w + 1; w2 < 10; w2++) { + yield [-v(x, y, w), -v(x, y, w2)]; + count++; + } + } + } + } + + console.log("maxOneValue: " + count); + + return null; +} + +export const length = 9 * 9 * (8 + 7 + 6 + 5 + 4 + 3 + 2 + 1); diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..682e43f --- /dev/null +++ b/src/util.ts @@ -0,0 +1,11 @@ +import { assert } from "console"; + +export function v(x: number, y: number, w: number): number { + assert(1 <= x && x <= 9); + assert(1 <= y && y <= 9); + assert(1 <= w && w <= 9); + + return x + 9 * (y - 1) + 81 * (w - 1); +} + +export type N = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; diff --git a/tsconfig.json b/tsconfig.json index 74f7a49..c25db5d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,6 @@ { "compilerOptions": { /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ @@ -9,7 +8,6 @@ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ @@ -23,7 +21,6 @@ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ "module": "commonjs" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ @@ -37,12 +34,10 @@ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ "resolveJsonModule": true /* Enable importing .json files. */, // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, "declarationMap": true /* Create sourcemaps for d.ts files. */, @@ -67,14 +62,12 @@ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ "declarationDir": "./dist/types" /* Specify the output directory for generated declaration files. */, // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - /* Type Checking */ "strict": true /* Enable all strict type-checking options. */, "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */, @@ -95,9 +88,12 @@ "noPropertyAccessFromIndexSignature": true /* Enforces using indexed accessors for keys declared using an indexed type. */, // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} + }, + "include": [ + "generateRules.ts", + "visualizeResult.ts" + ] +} \ No newline at end of file diff --git a/visualizeResult.ts b/visualizeResult.ts new file mode 100644 index 0000000..e69de29