1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! Sudoku puzzle solver and generator library.
//!
//! Sudokugen can find a solution to a valid puzzle using a mixture of basic strategies
//! and bruteforce. It can also generate new minimal puzzles.
//! This library was built as a rust learning project for myself.
//!
//! # How to use Sudokugen
//! Sudokugen offers two convenience functions, [`solve`] and [`generate`] to solve and generate
//! sudoku puzzles and a struct [`Board`] to help you inspect and manipulate them.
//!
//! You can parse a puzzle from a string:
//!
//! ```
//! use sudokugen::Board;
//!
//! let board: Board = "
//!      . . . | 4 . . | 8 7 .
//!      4 . 3 | . . . | . . .
//!      2 . . | . . 3 | . . 9
//!      ---------------------
//!      . . 6 | 2 . . | . . 7
//!      . . . | 9 . 6 | . . .
//!      3 . 9 | . 8 . | . . .
//!      ---------------------
//!      . . . | . . . | . 4 .
//!      8 7 2 | 5 . . | . . .
//!      . . . | 7 2 . | 6 . .
//! ".parse().unwrap();
//! ```
//! After it's parsed you can solve it using the [`solve`] function:
//! ```
//! use sudokugen::solve;
//! # use sudokugen::Board;
//! #
//! # let board: Board =
//! #    ". . . | 4 . . | 8 7 .
//! #     4 . 3 | . . . | . . .
//! #     2 . . | . . 3 | . . 9
//! #     ---------------------
//! #     . . 6 | 2 . . | . . 7
//! #     . . . | 9 . 6 | . . .
//! #     3 . 9 | . 8 . | . . .
//! #     ---------------------
//! #     . . . | . . . | . 4 .
//! #     8 7 2 | 5 . . | . . .
//! #     . . . | 7 2 . | 6 . .
//! #    "
//! #       .parse()
//! #       .unwrap();
//!
//! assert_eq!(
//!     solve(&board).unwrap(),
//!     "695412873413879526287653419146235987728946135359187264561398742872564391934721658"
//!     .parse()
//!     .unwrap()
//! );
//! ```
//!
//! Finally you can generate new puzzles using [`generate`], the parameter `3` here indicates that
//! you would like a puzzle of base size 3, which translates to a 9x9 puzzle.
//!
//! ```
//! use sudokugen::generate;
//!
//! let puzzle = generate(3);
//!
//! println!("Puzzle\n{}", puzzle.board());
//! println!("Solution\n{}", puzzle.solution());
//! ```
//! Which will print something like this:
//!
//! ```ignore
//! > Puzzle
//! > . . . . . . . 6 .
//! > . 1 7 . 4 . . 9 .
//! > . . . . 9 . 5 3 .
//! > . . 5 . 7 2 8 . .
//! > 1 . . . . 8 4 5 .
//! > . 4 . 9 . . . . .
//! > 8 7 9 1 2 . . . .
//! > 4 5 . 8 . . . . .
//! > . . . . . . . . .
//! >
//! > Solution
//! > 9 2 3 5 8 1 7 6 4
//! > 5 1 7 6 4 3 2 9 8
//! > 6 8 4 2 9 7 5 3 1
//! > 3 6 5 4 7 2 8 1 9
//! > 1 9 2 3 6 8 4 5 7
//! > 7 4 8 9 1 5 6 2 3
//! > 8 7 9 1 2 6 3 4 5
//! > 4 5 6 8 3 9 1 7 2
//! > 2 3 1 7 5 4 9 8 6
//! ```
//!
//! # Crate Layout
//! This crate is divided in three modules. [`board`] contains the tools needed to parse, manipulate and print
//! a puzzle and it's individual cells. [`solver`] contains the [`solve`] function and [`generator`] contains
//! the [`generate`] function as well as an umbrella struct to hold the puzzle and it's solution.
//!
//! # Puzzle quality
//! Grading puzzles is beyond the scope of this crate. The reason behind it is that grading puzzles
//! correctly, requires solving them like a human would and some of the more complex techniques to solve
//! a puzzle like a human would require a lot of computations that do not always payoff performance-wise.
//!
//! That being said, the generated puzzles consistently have between 22 and 26 clues making them likely
//! on the harder side of most generally available puzzles.
//!
//! # Is it fast?
//! The quick answer is, it depends on your use case. The [`solve`] function is optimized to be
//! decently fast for a 9x9 sudoku puzzle, in my 2017 MacBook Pro it takes an average of 300μs
//! to solve a difficult puzzle, that is around 3000 puzzles per second.
//!
//! The [`generate`] function is less optimized and makes heavy usage of [`solve`] without trying to
//! re-use repeated computations, as such it's much slower clocking at about 18ms to generate
//! a new puzzle in my benchmarks.
//!
//! You can run your own benchmarks with `cargo bench`
//!
//! [`solve`]: solver/fn.solve.html
//! [`solver`]: solver/index.html
//! [`generate`]: solver/generator/fn.generate.html
//! [`generator`]: solver/generator/index.html
//! [`Board`]: board/struct.Board.html
//! [`board`]: board/index.html

#![warn(missing_docs)]
#![warn(missing_doc_code_examples)]

pub mod board;
pub mod solver;

pub use board::Board;
pub use solver::generator::generate;
pub use solver::solve;