Skip to content

Commit 82e18fb

Browse files
authored
Merge pull request #13 from ArjArav98/refactor_to_c++_17
Rewrite in C++17 and add functionality
2 parents 4163218 + 44fd6ba commit 82e18fb

File tree

11 files changed

+1009
-1529
lines changed

11 files changed

+1009
-1529
lines changed

README.md

Lines changed: 216 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,225 @@
1-
# Introduction
2-
These are a suite of C++ programs which deal with Sudoku Puzzles. The name might be misleading, yes, but these programs don't just solve Sudoku puzzles, they also achieve other objectives such as Sudoku Puzzle Validation and Sudoku Puzzle Generation (Under development).
1+
# Sudoku-Suite
2+
A C++17-compatible header that provides useful functions which help with the solving, validation and generation of 9x9 Sudoku puzzles.
33

44
## Contents
5-
* [Sudoku Solver](#sudoku-solver)
6-
* [Getting Started (Usage)](#getting-started)
7-
* [How It Works](#how-it-works)
8-
* [Sudoku Validator](#sudoku-validator)
9-
* [Getting Started (Usage)](#getting-started-1)
10-
* [How It Works](#how-it-works-1)
5+
* [Usage](#usage)
6+
* [Documentation](#documentation)
7+
* [Examples](#examples)
8+
* [Solving and validating a Sudoku puzzle](#solving-and-validating-sudoku-puzzle)
9+
* [Generating a Sudoku puzzle](#generating-a-sudoku-puzzle)
10+
* [Initialising and reusing Grid objects](#initialising-and-reusing-grid-objects)
11+
* [Reading Sudoku puzzles from a file](#reading-sudoku-puzzles-from-a-file)
12+
* [Operations on Grid objects](#operations-on-grid-objects)
13+
* [How It Works](#sudoku-solver---how-it-works)
1114
* [Acknowledgements](#acknowledgements)
1215
* [Tools](#tools)
1316

14-
# Sudoku-Solver
15-
This is a program which solves 9x9 Sudoku puzzles. **Written completely in C++** and **built wholly from scratch**, this program reads input either from a user or from a file containing the Sudoku values and solves the puzzle. It employs concepts such as backtracking and recursion.
16-
17-
### Getting Started
18-
* Simply download the ```sudoku-solver.cpp``` file found in the ```Sudoku-Solver/``` directory. Run it using any standard C++ compiler. In case of any errors or compatibility issues, submit an issue in this git.
19-
* Once downloaded, compiled and run; the program will require the user to input the Sudoku puzzle into it. There are two ways to do this.
20-
* The user can either input the values manually one-by-one when the program is running.
21-
* The user can write all the values into a file, seperated by whitespaces. The file can have any name or extension. When the program is running, the user will be prompted to simply enter the name of the file (with extension). **Below** is an example of how the contents of such a file might look. Look at the ```sample.txt``` files in the same directory for more examples.
17+
## Usage
18+
19+
* Simply download the `src/sudoku_suite.h` file and move it to your project's directory.
20+
* Include the header file, as shown below in the examples, and use the functions you need!
21+
* **NOTE:** The code is incompatible with pre-C++17 versions. While compiling, you'll have to compile with the `--std=c++17` flag.
22+
* For example; when using the clang compiler, the compile command would be `c++ --std=c++17 /path/to/file.cpp`
23+
24+
## Documentation
25+
26+
There are **three functions** that Sudoku-Suite provides the developer, along with **one class**. They are as follows:-
27+
28+
* `Grid`
29+
* An object that represents a 9x9 Sudoku grid. The `Grid` object does not validate the grid in any way, i.e, it only holds the grid and values inside it.
30+
* While initialising, if the given values are invalid, an `std::invalid_argument` exception is thrown.
31+
* *Check out the examples below to see how we can initialise and use this object!*
32+
* `void solve(Grid *grid)`
33+
* A function that takes in a pointer to a `Grid` object and solves the Sudoku puzzle present in it. Returns nothing.
34+
* If the puzzle cannot be solved, a `std::logic_error` exception is thrown.
35+
* `bool is_valid_solution(Grid &grid)`
36+
* A function that takes in a `Grid` object and returns a `bool` with a value of `true` if the `Grid` object contains a finished and valid Sudoku solution.
37+
* `Grid generate_puzzle()`
38+
* A function that takes in nothing and returns a `Grid` object containing an unfinished Sudoku puzzle.
39+
40+
## Examples
41+
42+
**NOTE:** The following examples are also present in the repository in the `samples/` directory.
43+
44+
* [Solving and validating a Sudoku puzzle](#solving-and-validating-sudoku-puzzle)
45+
* [Generating a Sudoku puzzle](#generating-a-sudoku-puzzle)
46+
* [Initialising and reusing Grid objects](#initialising-and-reusing-grid-objects)
47+
* [Reading Sudoku puzzles from a file](#reading-sudoku-puzzles-from-a-file)
48+
* [Operations on Grid objects](#operations-on-grid-objects)
49+
50+
#### Solving and validating Sudoku puzzle
51+
```
52+
#include<iostream>
53+
#include"/path/to/sudoku_suite.h"
54+
55+
int main() {
56+
sudoku::Grid grid({{
57+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }}, // The 0s represent blank cells.
58+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
59+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
60+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
61+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
62+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
63+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
64+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
65+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
66+
}});
67+
68+
sudoku::solve(&grid);
69+
70+
std::cout << "Solution is valid? --> ";
71+
std::cout << sudoku::is_valid_solution(grid) << std::endl;
72+
73+
std::cout << grid << std::endl;
74+
75+
return 0;
76+
}
77+
```
78+
79+
#### Generating a Sudoku puzzle
80+
```
81+
#include<iostream>
82+
#include"/path/to/sudoku_suite.h"
83+
84+
int main() {
85+
sudoku::Grid grid = sudoku::generate_puzzle();
86+
std::cout << grid << std::endl;
87+
88+
return 0;
89+
}
90+
```
91+
92+
#### Initialising and reusing Grid objects
93+
```
94+
#include<iostream>
95+
#include"/path/to/sudoku_suite.h"
96+
97+
int main() {
98+
//================
99+
// Method 1: Use the constructor and pass in a
100+
// 2D matrix of values.
101+
//================
102+
103+
sudoku::Grid grid({{
104+
{{ 0, 0, 0, 0, 0, 0, 6, 8, 0 }},
105+
{{ 0, 0, 0, 0, 7, 3, 0, 0, 9 }},
106+
{{ 3, 0, 9, 0, 0, 0, 0, 4, 5 }},
107+
{{ 4, 9, 0, 0, 0, 0, 0, 0, 0 }},
108+
{{ 8, 0, 3, 0, 5, 0, 9, 0, 2 }},
109+
{{ 0, 0, 0, 0, 0, 0, 0, 3, 6 }},
110+
{{ 9, 6, 0, 0, 0, 0, 3, 0, 8 }},
111+
{{ 7, 0, 0, 6, 8, 0, 0, 0, 0 }},
112+
{{ 0, 2, 8, 0, 0, 0, 0, 0, 0 }}
113+
}});
114+
std::cout << grid << std::endl;
115+
116+
//================
117+
// Method 2: Declare a 2D matrix of values and pass it
118+
// into the set_initial_state() method.
119+
//================
120+
121+
std::array<std::array<int, 9>, 9> values = {{
122+
{{ 9, 7, 8, 4, 1, 0, 0, 0, 5 }},
123+
{{ 3, 0, 0, 8, 0, 0, 0, 6, 4 }},
124+
{{ 6, 0, 0, 3, 5, 0, 0, 9, 0 }},
125+
{{ 2, 6, 9, 0, 3, 0, 0, 0, 7 }},
126+
{{ 5, 0, 7, 1, 0, 0, 0, 0, 0 }},
127+
{{ 1, 0, 3, 0, 0, 2, 0, 8, 9 }},
128+
{{ 7, 1, 0, 2, 0, 5, 0, 0, 3 }},
129+
{{ 0, 0, 2, 7, 0, 3, 1, 5, 8 }},
130+
{{ 0, 0, 5, 9, 4, 1, 0, 0, 0 }}
131+
}};
132+
grid.set_initial_state(values);
133+
std::cout << grid << std::endl;
134+
135+
//================
136+
// Method 3: Read the initial state of the puzzle
137+
// from a file.
138+
//================
22139
23-
```
24-
0 0 0 0 0 0 6 8 0
25-
0 0 0 0 7 3 0 0 9
26-
3 0 9 0 0 0 0 4 5
27-
28-
4 9 0 0 0 0 0 0 0
29-
8 0 3 0 5 0 9 0 2
30-
0 0 0 0 0 0 0 3 6
31-
32-
9 6 0 0 0 0 3 0 8
33-
7 0 0 6 8 0 0 0 0
34-
0 2 8 0 0 0 0 0 0
35-
```
36-
37-
* Once solved, the Sudoku puzzles shall be displayed like this.
38-
```
39-
++=====================================++
40-
|| 1 7 2 || 5 4 9 || 6 8 3 ||
41-
++-----------++-----------++-----------++
42-
|| 6 4 5 || 8 7 3 || 2 1 9 ||
43-
++-----------++-----------++-----------++
44-
|| 3 8 9 || 2 6 1 || 7 4 5 ||
45-
++=====================================++
46-
|| 4 9 6 || 3 2 7 || 8 5 1 ||
47-
++-----------++-----------++-----------++
48-
|| 8 1 3 || 4 5 6 || 9 7 2 ||
49-
++-----------++-----------++-----------++
50-
|| 2 5 7 || 1 9 8 || 4 3 6 ||
51-
++=====================================++
52-
|| 9 6 4 || 7 1 5 || 3 2 8 ||
53-
++-----------++-----------++-----------++
54-
|| 7 3 1 || 6 8 2 || 5 9 4 ||
55-
++-----------++-----------++-----------++
56-
|| 5 2 8 || 9 3 4 || 1 6 7 ||
57-
++=====================================++
58-
```
59-
60-
### How It Works
140+
grid.set_initial_state_from_file("path/to/sample1.txt");
141+
std::cout << grid << std::endl;
142+
143+
return 0;
144+
}
145+
```
146+
147+
#### Reading Sudoku puzzles from a file
148+
149+
File: `sample1.txt`
150+
```
151+
5 3 0 0 7 0 0 0 0
152+
6 0 0 1 9 5 0 0 0
153+
0 9 8 0 0 0 0 6 0
154+
8 0 0 0 6 0 0 0 3
155+
4 0 0 8 0 3 0 0 1
156+
7 0 0 0 2 0 0 0 6
157+
0 6 0 0 0 0 2 8 0
158+
0 0 0 4 1 9 0 0 5
159+
0 0 0 0 8 0 0 7 9
160+
```
161+
162+
```
163+
#include<iostream>
164+
#include"/path/to/sudoku_suite.h"
165+
166+
int main() {
167+
sudoku::Grid grid;
168+
grid.set_initial_state_from_file("sample1.txt");
169+
std::cout << grid << std::endl;
170+
171+
sudoku::solve(&grid);
172+
std::cout << grid << std::endl;
173+
174+
return 0;
175+
}
176+
```
177+
178+
#### Operations on Grid objects
179+
```
180+
#include<iostream>
181+
#include"/path/to/sudoku_suite.h"
182+
183+
int main() {
184+
185+
sudoku::Grid sample_grid_1({{
186+
{{ 1, 7, 2, 5, 4, 9, 6, 8, 3 }},
187+
{{ 6, 4, 5, 8, 7, 3, 2, 1, 9 }},
188+
{{ 3, 8, 9, 2, 6, 1, 7, 4, 5 }},
189+
{{ 4, 9, 6, 3, 2, 7, 8, 5, 1 }},
190+
{{ 8, 1, 3, 4, 5, 6, 9, 7, 2 }},
191+
{{ 2, 5, 7, 1, 9, 8, 4, 3, 6 }},
192+
{{ 9, 6, 4, 7, 1, 5, 3, 2, 8 }},
193+
{{ 7, 3, 1, 6, 8, 2, 5, 9, 4 }},
194+
{{ 5, 2, 8, 9, 3, 4, 1, 6, 7 }}
195+
}});
196+
197+
sudoku::Grid sample_grid_2({{
198+
{{ 1, 7, 2, 5, 4, 9, 6, 8, 3 }},
199+
{{ 6, 4, 5, 8, 7, 3, 2, 1, 9 }},
200+
{{ 3, 8, 9, 2, 6, 1, 7, 4, 5 }},
201+
{{ 4, 9, 6, 3, 2, 7, 8, 5, 1 }},
202+
{{ 8, 1, 3, 4, 5, 6, 9, 7, 2 }},
203+
{{ 2, 5, 7, 1, 9, 8, 4, 3, 6 }},
204+
{{ 9, 6, 4, 7, 1, 5, 3, 2, 8 }},
205+
{{ 7, 3, 1, 6, 8, 2, 5, 9, 4 }},
206+
{{ 5, 2, 8, 9, 3, 4, 1, 6, 7 }}
207+
}});
208+
209+
if (sample_grid_1 == sample_grid_2) std::cout << "They're the same! \n\n";
210+
211+
// Get grid value for coordinate.
212+
std::pair<int, int> last_coord = std::make_pair(8, 8);
213+
int last_value = sample_grid_1.get(last_coord);
214+
215+
// Print the grid to the console.
216+
std::cout << sample_grid_2 << std::endl;
217+
218+
return 0;
219+
}
220+
```
221+
222+
### Sudoku Solver - How It Works
61223
This particular algorithm employs the use of backtracking, one of the more common methods to solve Sudoku puzzles. I've written a simple algorithm to give an idea of how the program works.
62224

63225
1. Start.
@@ -69,47 +231,6 @@ This particular algorithm employs the use of backtracking, one of the more commo
69231
7. The puzzle has now been solved.
70232
8. Stop.
71233

72-
# Sudoku Validator
73-
This is a program which validates solutions for 9x9 Sudoku puzzles. **Written completely in C++** and **built wholly from scratch**, this program takes in input from the user or from a file containing the values. It then validates the puzzle and then displays whether it is a valid solution or not.
74-
75-
### Getting Started
76-
* Simply download the ```sudoku-validator.cpp``` file found in the ```Sudoku-Validator``` directory. Run it using any standard C++ compiler. In case of any errors or compatibility issues, submit an issue in this git.
77-
* Once downloaded, compiled and run; the program will require the user to input the Sudoku puzzle into it. There are two ways to do this.
78-
* The user can either input the values manually one-by-one when the program is running.
79-
* The user can write all the values into a file, seperated by whitespaces. The file can have any name or extension. When the program is running, the user will be prompted to simply enter the name of the file (with extension). **Below** is an example of how the contents of such a file might look. Look at the ```sample.txt``` files in the same directory for more examples.
80-
81-
```
82-
8 4 6 9 3 7 1 5 2
83-
3 1 9 6 2 5 8 4 7
84-
7 5 2 1 8 4 9 6 3
85-
86-
2 8 5 7 1 3 6 9 4
87-
4 6 3 8 5 9 2 7 1
88-
9 7 1 2 4 6 3 8 5
89-
90-
1 2 7 5 9 8 4 3 6
91-
6 3 8 4 7 1 5 2 9
92-
5 9 4 3 6 2 7 1 8
93-
```
94-
95-
96-
### How It Works
97-
The workings of the Sudoku Validator are quite simple, to be honest. Here's a simple algorithm explaining them all.
98-
99-
1. Start
100-
2. The values in all the cells are checked to see if they are in the range 1-9. If not, the puzzle is invalid.
101-
3. Every row is checked to see if it contains 1-9 atleast once. If not, the solution is invalid.
102-
4. Every column is checked to see if it contains 1-9 atleast once. If not, the solution is invalid.
103-
4. Every 3x3 grid is checked to see if it contains 1-9 atleast once. If not, the solution is invalid.
104-
5. If all the criteria have been satisfied, the solution is valid.
105-
6. Stop
106-
107-
## Future Direction
108-
109-
* Right now, the Sudoku Solver Suite is just a CLI application with a I/O interface. However, if we could make it into a CLI utility which takes in inputs through parameters and switches, that would make it easier for other developers to reuse.
110-
* I was thinking we could write a "backend" which could then be called by various "interface frontends". The backend is written in C++ and the frontends could be shell or maybe an API or something.
111-
* The objective would be for this to be used by web backends and things like that.
112-
113234
## Acknowledgements
114235

115236
* Shriram R - Idea Inspiration

0 commit comments

Comments
 (0)