sudoku-pro 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +19 -0
  2. package/license +20 -0
  3. package/package.json +47 -0
  4. package/sudoku-pro.js +185 -0
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # sudoku-pro: Sudoku Generator and Sudoku Solver
2
+
3
+ sudoku-pro is a Node.js package that provides functionalities to generate, solve, and print Sudoku puzzles of varying difficulty levels using the backtracking algorithm. It offers an easy-to-use interface to create Sudoku puzzles for entertainment and educational purposes. The main idea behind this package was to test the potential of the backtracking algorithm for generating Sudoku puzzles of different difficulty levels, making it suitable for both recreational and educational purposes.
4
+
5
+ ## Installation
6
+
7
+ You can install the package via npm:
8
+
9
+ ```bash
10
+ npm i sudoku-pro
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```npm
16
+ npm run easy
17
+ npm run medium
18
+ npm run hard
19
+ ```
package/license ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2016 Ashish Vashisht <concur.dev@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "sudoku-pro",
3
+ "version": "1.0.0",
4
+ "description": "sudoku-pro humbly presents itself as your go-to Node.js toolkit for generating, solving, and printing Sudoku puzzles spanning different difficulty levels. Powered by the reliable backtracking algorithm, it aspires to offer enthusiasts and learners alike a simple yet effective platform to engage with Sudoku puzzles. With Sudoku-Pro, embark on a journey of brain-teasing challenges or delve into educational endeavors with ease. Our humble interface aims to make Sudoku puzzle creation and enjoyment accessible to all, ensuring a delightful experience for users of varying skill levels. Join us in exploring the possibilities of Sudoku puzzles while we humbly accompany you on your puzzle-solving adventures.",
5
+ "main": "sudoku-pro.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+ssh://git@github.com/concurdev/sudoku-pro.git"
9
+ },
10
+ "scripts": {
11
+ "easy": "node sudoku-pro e",
12
+ "medium": "node sudoku-pro m",
13
+ "hard": "node sudoku-pro h"
14
+ },
15
+ "files": [
16
+ "sudoku-pro.js"
17
+ ],
18
+ "keywords": [
19
+ "Sudoku",
20
+ "Puzzle",
21
+ "Game",
22
+ "Logic",
23
+ "Numbers",
24
+ "Board",
25
+ "Generator",
26
+ "Solver",
27
+ "Difficulty",
28
+ "Easy",
29
+ "Medium",
30
+ "Hard",
31
+ "Logic Game",
32
+ "Recreational Mathematics",
33
+ "Brain Teaser",
34
+ "Puzzle Game",
35
+ "Numbers Game"
36
+ ],
37
+ "author": "Ashish Vashisht",
38
+ "license": "MIT",
39
+ "engines": {
40
+ "node": ">= 10"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/concurdev/sudoku-pro/issues"
44
+ },
45
+ "homepage": "https://github.com/concurdev/sudoku-pro#readme",
46
+ "devDependencies": {}
47
+ }
package/sudoku-pro.js ADDED
@@ -0,0 +1,185 @@
1
+ // Get the difficulty level
2
+ const args = process.argv.slice(2);
3
+
4
+ function shuffle(array) {
5
+ // Fisher-Yates shuffle algorithm
6
+ for (let i = array.length - 1; i > 0; i--) {
7
+ const j = Math.floor(Math.random() * (i + 1));
8
+ [array[i], array[j]] = [array[j], array[i]];
9
+ }
10
+ return array;
11
+ }
12
+
13
+ function generateSudoku(difficulty) {
14
+ const sudoku = Array.from({ length: 9 }, () => Array(9).fill(0));
15
+
16
+ // Fill the diagonal blocks (3x3 sub-grids) with valid numbers
17
+ for (let i = 0; i < 9; i += 3) {
18
+ const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];
19
+ shuffle(nums);
20
+ for (let j = 0; j < 3; j++) {
21
+ for (let k = 0; k < 3; k++) {
22
+ sudoku[i + j][i + k] = nums.pop();
23
+ }
24
+ }
25
+ }
26
+
27
+ // Solve the puzzle
28
+ solveSudoku(sudoku);
29
+
30
+ // Determine the number of cells to remove based on difficulty level
31
+ let numToRemove;
32
+ if (difficulty === 'e') {
33
+ numToRemove = Math.floor(Math.random() * 20) + 20; // Easy difficulty
34
+ } else if (difficulty === 'm') {
35
+ numToRemove = Math.floor(Math.random() * 25) + 40; // Medium difficulty
36
+ } else if (difficulty === 'h') {
37
+ numToRemove = Math.floor(Math.random() * 30) + 55; // Hard difficulty
38
+ } else {
39
+ throw new Error('Invalid difficulty level. Please use "e" for easy, "m" for medium, or "h" for hard.');
40
+ }
41
+
42
+ // Remove some numbers to create the puzzle
43
+ for (let i = 0; i < numToRemove; i++) {
44
+ const row = Math.floor(Math.random() * 9);
45
+ const col = Math.floor(Math.random() * 9);
46
+ if (sudoku[row][col] !== 0) {
47
+ sudoku[row][col] = 0;
48
+ } else {
49
+ i--; // Try again if the cell is already empty
50
+ }
51
+ }
52
+
53
+ return sudoku;
54
+ }
55
+
56
+ function solveSudoku(sudoku) {
57
+ const emptyCell = findEmptyCell(sudoku);
58
+ if (!emptyCell) {
59
+ return true; // Puzzle solved successfully
60
+ }
61
+
62
+ const [row, col] = emptyCell;
63
+ for (let num = 1; num <= 9; num++) {
64
+ if (isValidMove(sudoku, row, col, num)) {
65
+ sudoku[row][col] = num;
66
+ if (solveSudoku(sudoku)) {
67
+ return true;
68
+ }
69
+ sudoku[row][col] = 0; // Undo the assignment
70
+ }
71
+ }
72
+
73
+ return false; // No solution found, backtrack
74
+ }
75
+
76
+ function findEmptyCell(sudoku) {
77
+ // Function to find an empty cell in the Sudoku grid
78
+ for (let row = 0; row < 9; row++) {
79
+ for (let col = 0; col < 9; col++) {
80
+ if (sudoku[row][col] === 0) {
81
+ return [row, col];
82
+ }
83
+ }
84
+ }
85
+ return null; // No empty cell found
86
+ }
87
+
88
+ function isValidMove(sudoku, row, col, num) {
89
+ // Check if assigning num to the cell at (row, col) is a valid move
90
+ // Check row
91
+ for (let i = 0; i < 9; i++) {
92
+ if (sudoku[row][i] === num) {
93
+ return false; // Number already exists in the row
94
+ }
95
+ }
96
+
97
+ // Check column
98
+ for (let i = 0; i < 9; i++) {
99
+ if (sudoku[i][col] === num) {
100
+ return false; // Number already exists in the column
101
+ }
102
+ }
103
+
104
+ // Check 3x3 subgrid
105
+ const startRow = Math.floor(row / 3) * 3;
106
+ const startCol = Math.floor(col / 3) * 3;
107
+ for (let i = 0; i < 3; i++) {
108
+ for (let j = 0; j < 3; j++) {
109
+ if (sudoku[startRow + i][startCol + j] === num) {
110
+ return false; // Number already exists in the subgrid
111
+ }
112
+ }
113
+ }
114
+
115
+ return true; // Valid move
116
+ }
117
+
118
+ function printSudoku(sudoku) {
119
+ console.log("Sudoku Puzzle:");
120
+ console.log("-------------------------");
121
+ sudoku.forEach((row, rowIndex) => {
122
+ if (rowIndex % 3 === 0 && rowIndex !== 0) {
123
+ console.log("------|-------|-------");
124
+ }
125
+ row.forEach((cell, cellIndex) => {
126
+ if (cellIndex % 3 === 0 && cellIndex !== 0) {
127
+ process.stdout.write("| ");
128
+ }
129
+ process.stdout.write(String(cell || '.') + ' ');
130
+ if (cellIndex === 8) {
131
+ console.log();
132
+ }
133
+ });
134
+ });
135
+ console.log("-------------------------");
136
+ }
137
+
138
+ function printSudokuWithAnswers(sudoku) {
139
+ console.log("Sudoku Puzzle with Answers:");
140
+ console.log("-------------------------");
141
+ sudoku.forEach((row, rowIndex) => {
142
+ if (rowIndex % 3 === 0 && rowIndex !== 0) {
143
+ console.log("------|-------|-------");
144
+ }
145
+ row.forEach((cell, cellIndex) => {
146
+ if (cellIndex % 3 === 0 && cellIndex !== 0) {
147
+ process.stdout.write("| ");
148
+ }
149
+ process.stdout.write(String(cell) + ' ');
150
+ if (cellIndex === 8) {
151
+ console.log();
152
+ }
153
+ });
154
+ });
155
+ console.log("-------------------------");
156
+ // set flag to true and clear interval
157
+ sudokuPrinted = true;
158
+ clearInterval(intervalId);
159
+ }
160
+
161
+ const difficulty = args[0]; // Get the difficulty level from command line arguments
162
+
163
+ let sudokuPrinted = false;
164
+
165
+ // Set interval to run every 5 seconds
166
+ const intervalId = setInterval(() => {
167
+ // Check if sudokuPrinted is true
168
+ if (sudokuPrinted) {
169
+ // If sudokuPrinted is true, clear the interval
170
+ clearInterval(intervalId);
171
+ } else {
172
+ // If sudokuPrinted is false, continue executing
173
+ const sudoku = generateSudoku(difficulty);
174
+ printSudoku(sudoku);
175
+ solveSudoku(sudoku); // Solve the generated puzzle
176
+ printSudokuWithAnswers(sudoku);
177
+ }
178
+ }, 5000);
179
+
180
+ module.exports = {
181
+ generateSudoku,
182
+ printSudoku,
183
+ solveSudoku,
184
+ printSudokuWithAnswers
185
+ };