pub struct Sudoku {
pub cells: [u8; 81],
/* private fields */
}Expand description
A zero-allocation Sudoku board and solver.
The entire state (cells + bitboard constraints + empty-cell work list) fits
in a single #[repr(C, align(64))] struct (~216 bytes), keeping all working
data in L1 cache throughout the solve.
§Examples
Parse and solve:
use sudoku::Sudoku;
let mut sudoku: Sudoku = "530070000600195000098000060800060003\
400803001700020006060000280000419005\
000080079"
.parse()
.unwrap();
assert!(sudoku.solve());
// Every cell is now filled with a valid digit.
assert!(sudoku.cells().iter().all(|&v| v >= 1 && v <= 9));Detect an invalid puzzle:
use sudoku::{Sudoku, ParseError};
let result = "119000000000000000000000000000000000\
000000000000000000000000000000000000\
00000000000".parse::<Sudoku>();
assert!(result.is_err());Fields§
§cells: [u8; 81]Raw cell values: 0 = empty, 1–9 = placed digit.
Implementations§
Source§impl Sudoku
impl Sudoku
Sourcepub fn from_string(s: &str) -> Option<Self>
pub fn from_string(s: &str) -> Option<Self>
Parses a Sudoku from a string of exactly 81 ASCII digits ('0' = empty).
Prefer the FromStr implementation (.parse()) in new code;
this method is kept for backwards compatibility.
Returns None on any parse error. Use .parse::<Sudoku>() to
obtain a detailed ParseError instead.
§Examples
use sudoku::Sudoku;
let puzzle = "0".repeat(81);
assert!(Sudoku::from_string(&puzzle).is_some());
assert!(Sudoku::from_string("short").is_none());Sourcepub fn cells(&self) -> &[u8; 81]
pub fn cells(&self) -> &[u8; 81]
Returns a reference to the 81-element cell array.
Each element is 0 (empty) or a digit 1–9.
§Examples
use sudoku::Sudoku;
let sudoku: Sudoku = "0".repeat(81).parse().unwrap();
assert_eq!(sudoku.cells().len(), 81);
assert!(sudoku.cells().iter().all(|&v| v == 0));Sourcepub fn is_solved(&self) -> bool
pub fn is_solved(&self) -> bool
Returns true if every cell has been filled (no zeros remain).
§Examples
use sudoku::Sudoku;
let mut s: Sudoku = "0".repeat(81).parse().unwrap();
assert!(!s.is_solved());
s.solve();
assert!(s.is_solved());Sourcepub fn get(&self, r: usize, c: usize) -> u8
pub fn get(&self, r: usize, c: usize) -> u8
Returns the digit at row r, column c (both 0-indexed).
Returns 0 if the cell is empty.
§Panics
Panics if r >= 9 or c >= 9.
§Examples
use sudoku::Sudoku;
let s: Sudoku = "530070000600195000098000060800060003\
400803001700020006060000280000419005\
000080079".parse().unwrap();
assert_eq!(s.get(0, 0), 5);
assert_eq!(s.get(0, 1), 3);
assert_eq!(s.get(0, 2), 0); // emptySourcepub fn solve(&mut self) -> bool
pub fn solve(&mut self) -> bool
Solves the puzzle in place using MRV backtracking with bitboard constraint propagation.
Returns true if a solution was found (cells are updated), or false
if the puzzle has no solution (cells are unchanged).
§Examples
use sudoku::Sudoku;
// Arto Inkala's "AI Sudoku" (2010) — rated world's hardest at the time.
let mut s: Sudoku = "800000000003600000070090200050007000\
000045700000100030001000068008500010\
090000400".parse().unwrap();
assert!(s.solve());
assert!(s.is_solved());Sourcepub fn to_digit_string(&self) -> String
pub fn to_digit_string(&self) -> String
Returns the board as an 81-character string of digits ('0' = empty).
§Examples
use sudoku::Sudoku;
let puzzle = "0".repeat(81);
let s: Sudoku = puzzle.parse().unwrap();
assert_eq!(s.to_digit_string(), puzzle);Sourcepub fn print_grid(&self)
pub fn print_grid(&self)
Prints the board as a human-readable 9×9 grid with box dividers to stdout.
Trait Implementations§
Source§impl Default for Sudoku
Creates an empty board where every cell is unset.
impl Default for Sudoku
Creates an empty board where every cell is unset.
§Examples
use sudoku::Sudoku;
let mut s = Sudoku::default();
assert!(!s.is_solved());
assert!(s.solve()); // any valid completion existsSource§impl Display for Sudoku
Displays the board as an 81-character digit string (same as to_digit_string).
impl Display for Sudoku
Displays the board as an 81-character digit string (same as to_digit_string).
§Examples
use sudoku::Sudoku;
let s: Sudoku = "0".repeat(81).parse().unwrap();
assert_eq!(format!("{}", s), "0".repeat(81));Source§impl FromStr for Sudoku
impl FromStr for Sudoku
Source§fn from_str(s: &str) -> Result<Self, Self::Err>
fn from_str(s: &str) -> Result<Self, Self::Err>
Parses a Sudoku from a string of exactly 81 ASCII digits.
§Errors
Returns ParseError::InvalidLength if s.len() != 81,
ParseError::InvalidCharacter for non-digit bytes, or
ParseError::DuplicateDigit if any digit appears twice in a
row, column, or 3×3 box.
§Examples
use sudoku::Sudoku;
let s: Sudoku = "800000000003600000070090200050007000\
000045700000100030001000068008500010\
090000400".parse().unwrap();
assert_eq!(s.get(0, 0), 8);