# Exact Cover This crate provides an implementation of Knuth's [Algorithm X] for solving [exact cover] problems. The algorithms and data structures in this module, as well as the terminology of "options" and "items", come from Donald Knuth's The Art of Computer Programming, section 7.2.2, . [Algorithm X]: https://en.wikipedia.org/wiki/Knuth%27s_Algorithm_X [exact cover]: https://en.wikipedia.org/wiki/Exact_cover * No dependencies * 100% safe Rust * Choose whether to find a single solution or all possible solutions * Designed for flexibility (see below) From a high level, Algorithm X is simply a backtracking exhaustive search algorithm. At a lower level, Algorithm X cleverly manipulates linked lists using the "dancing links" technique to make the backtracking more efficient. This crate implements the backtracking search as a provided trait method [`ExactCoverProblem::search`], while the dancing links data structure and operations are implemented by the [`Dlx`] struct. A custom implementation of the `ExactCoverProblem` trait can make use of the dancing links structure provided by `Dlx`, control the order items are selected for covering, and apply additional filters to options for problems beyond pure exact cover. A ready-to-use implementation using the *minimum remaining values* heuristic to select items (i.e. select the item covered by the fewest number of available options) is provided with [`MrvExactCoverSearch`]. Its code can be helpful as a starting point for custom implementations. ## Examples The following pure exact cover problem is often used as an example in texts by Knuth, and consists of 7 items and 6 options. For a more practical application, see `examples/sudoku.rs`. ```rust # use xcov::*; let mut builder = DlxBuilder::new(7, 0); builder.add_option(&[ 3, 5 ]); builder.add_option(&[1, 4, 7]); builder.add_option(&[ 2, 3, 6 ]); builder.add_option(&[1, 4, 6 ]); builder.add_option(&[ 2, 7]); builder.add_option(&[ 4, 5, 7]); let mut problem = MrvExactCoverSearch::new(builder.build()); problem.search(); let solution = problem .current_solution() .expect("this example problem has a solution") .into_iter() .collect::>(); assert_eq!( solution, [ &[1, 4, 6][..], &[2, 7], &[3, 5], ] ); // can look for additional solutions but this problem has none assert!(!problem.search()); assert!(problem.current_solution().is_none()); ```