-
Notifications
You must be signed in to change notification settings - Fork 0
/
domino_chessboard.rs
46 lines (40 loc) · 1.77 KB
/
domino_chessboard.rs
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
/// This program determines in how many ways can 32 dominoes fill an $8\times8$
/// chessboard. We set up an exact cover problem with one item for each of the
/// $8\times8=64$ cells, and one option for each of the $2\times8\times7=112$
/// placements of a domino.
///
/// P. W. Kasteleyn obtained a closed formula for the number of domino coverings
/// of an $m\times n$ rectangle \[_Physica_ **27** (1961), pp. 1209–1225].
/// Interested readers can learn more by working out exercise 7.51 in the second
/// edition of the book _Concrete Mathematics_ (Addison–Wesley, 1994) by R. Graham,
/// D. E. Knuth and O. Patashnik.
use exact_covers::{DlSolver, Solver};
/// The number $m$ of rows of the board, also known as _ranks_.
const ROWS: u8 = 8;
/// The number $n$ of columns of the board, also known as _files_.
const COLUMNS: u8 = 8;
fn main() {
// Generate all cells of an $m\times n$ board.
let cells: Vec<_> = (0..ROWS)
.flat_map(|x| (0..COLUMNS).map(move |y| (x, y)))
.collect();
let mut solver: DlSolver<_, ()> = DlSolver::new(&cells, &[]);
// There's an option for each pair of adjacent cells. We start with the
// $m(n-1)$ horizontal placements,
for x0 in 0..ROWS {
for y0 in 0..COLUMNS - 1 {
solver.add_option([(x0, y0), (x0, y0 + 1)], []);
}
}
// and continue with the $n(m-1)$ vertical ones. To reduce symmetry, insist
// that the domino occupying the upper left cell is laid out horizontally.
for y0 in 0..COLUMNS {
for x0 in (y0 == 0) as u8..ROWS - 1 {
solver.add_option([(x0, y0), (x0 + 1, y0)], []);
}
}
// Count the number of solutions, taking symmetry into account.
let mut count = 0;
solver.solve(|_| count += 2);
assert_eq!(count, 12_988_816);
}