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
//! Sudoku puzzle solver and generator library.
//!
//! Sudokugen can find a solution to a valid puzzle using a mixture of basic strategies
//! and brute force. It can also generate new minimal puzzles.
//! This library was built as a rust learning project for myself.
//!
//! # How to use Sudokugen
//! Sudokugen uses two structures to parse, manipulate and display a sudoku, a board and puzzle.
//! The [Board] structure allows you to parse a board from a string, display it and try to solve it.
//! The [Puzzle] structure contains the information relevant for a new puzzle, the initial board and it's solution.
//!
//! You can parse a board 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 [Board::solve] function:
//! ```
//! # use sudokugen::Board;
//! #
//! # let mut 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();
//! #
//! board.solve().unwrap();
//! assert_eq!(
//! board,
//! "695412873413879526287653419146235987728946135359187264561398742872564391934721658"
//! .parse()
//! .unwrap()
//! );
//! ```
//!
//! Finally you can generate new puzzles using [Puzzle::generate], when doing this you must specify what size of puzzle
//! do you want to generate, [BoardSize] makes that easy.
//!
//! ```
//! use sudokugen::{Puzzle, BoardSize};
//!
//! let puzzle = Puzzle::generate(BoardSize::NineByNine);
//!
//! 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 its individual cells. [`solver`] extends [`board::Board`] with the [`board::Board::solve`] function and [`solver::generator`] contains
//! the [Puzzle] structure and it's static [`Puzzle::generate`] function.
//!
//! # 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 [`Board::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 [`Puzzle::generate`] function is less optimized and makes heavy usage of [`Board::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`
#![warn(missing_docs)]
#![warn(rustdoc::missing_doc_code_examples)]
pub mod board;
pub mod solver;
pub use board::Board;
pub use board::BoardSize;
pub use solver::generator::Puzzle;