Skip to main content

Sudoku

Struct Sudoku 

Source
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, 19 = placed digit.

Implementations§

Source§

impl Sudoku

Source

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());
Source

pub fn cells(&self) -> &[u8; 81]

Returns a reference to the 81-element cell array.

Each element is 0 (empty) or a digit 19.

§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));
Source

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());
Source

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); // empty
Source

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());
Source

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);
Source

pub fn print_grid(&self)

Prints the board as a human-readable 9×9 grid with box dividers to stdout.

Trait Implementations§

Source§

impl Clone for Sudoku

Source§

fn clone(&self) -> Sudoku

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Sudoku

Formats the board as a compact digit string (identical to [Display]).

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

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 exists
Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

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§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl FromStr for Sudoku

Source§

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);
Source§

type Err = ParseError

The associated error which can be returned from parsing.
Source§

impl PartialEq for Sudoku

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for Sudoku

Source§

impl Eq for Sudoku

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.