pub struct Solution<'s, 'i: 's, I, C, S> { /* private fields */ }Expand description
An iterator over the options of a solution to an XCC problem.
Implementations§
Source§impl<'s, 'i, S, I, C> Solution<'s, 'i, I, C, S>
impl<'s, 'i, S, I, C> Solution<'s, 'i, I, C, S>
Sourcepub fn next(&mut self, result: &mut Vec<&'i I>) -> bool
pub fn next(&mut self, result: &mut Vec<&'i I>) -> bool
Places the items in the next option of the solution into result.
Returns false and leaves the vector untouched if and only if
all options have already been enumerated.
Examples found in repository?
examples/langford_pairs.rs (line 61)
38fn main() {
39 let numbers = (1..=N).map(Item::Number);
40 let slots = (1..=2 * N).map(Item::Slot);
41 let items: Vec<_> = numbers.chain(slots).collect();
42
43 let mut solver: DlSolver<Item, ()> = DlSolver::new(&items, &[]);
44 for i in 1..=N {
45 // Optimization: half of the Langford pairs for a given value of $n$
46 // are the reverses of the others. Reduce the search space by placing
47 // the first 1 in position $1\le s_j<n$.
48 let first_slot_range = 1..if i == 1 { N } else { 2 * N - i };
49 for j in first_slot_range {
50 let k = i + j + 1;
51 let items = [Item::Number(i), Item::Slot(j), Item::Slot(k)];
52 solver.add_option(items, []);
53 }
54 }
55
56 let mut options = Vec::new();
57 solver.solve(|mut solution| {
58 assert_eq!(solution.option_count(), N);
59 // Convert the set of options into the corresponding placement.
60 let mut placement = [0usize; 2 * N];
61 while solution.next(&mut options) {
62 // Sort the items in `options` so we can perform pattern matching.
63 // Note that `Item` derives `Ord`, so item variants are ordered by
64 // their discriminants: numbers come before slots.
65 options.sort();
66 if let &[&Item::Number(i), &Item::Slot(j), &Item::Slot(k)] = &options[..] {
67 placement[j - 1] = i;
68 placement[k - 1] = i;
69 } else {
70 unreachable!("ordered option should match (number, slot, slot) pattern");
71 }
72 }
73 // Print the found Langford sequence, and its reverse.
74 println!("{:?}", placement);
75 placement.reverse();
76 println!("{:?}", placement);
77 });
78}More examples
examples/polycube_packing.rs (line 186)
149fn main() {
150 // Define the items of the exact cover problem, namely the $lmn$ cells of
151 // the $l\times m\times n$ cuboid.
152 let (l, m, n) = (5i8, 5i8, 5i8);
153 let positions = (0..l)
154 .flat_map(|x| iter::repeat(x).zip(0..m))
155 .flat_map(|y| iter::repeat(y).zip(0..n))
156 .map(|((x, y), z)| (x, y, z))
157 .collect::<Vec<_>>();
158
159 let mut solver: DlSolver<Position, ()> = DlSolver::new(&positions, &[]);
160 // For each base placement $P$ of the Y pentacube, and for each offset
161 // $(x_0,y_0,z_0)$ such that the piece $P'=P+(x_0,y_0,z_0)$ lies within the
162 // $l\times m\times n$ cuboid cornered at the origin, define an option whose
163 // primary items are the cells of $P'$. We break symmetry by constraining
164 // a particular cubie of the first pentacube to be at $L_\infty$ distance
165 // $\le2$ from the origin.
166 let placements = Y.base_placements();
167 let mut first = true;
168 for placement in placements {
169 for (x_0, y_0, z_0) in &positions {
170 if first && (*x_0 > 2 || *y_0 > 2 || *z_0 > 2) {
171 continue;
172 }
173 let shifted = placement.transform(|(x, y, z)| (x + x_0, y + y_0, z + z_0));
174 if is_in_bounds(&shifted, l, m, n) {
175 solver.add_option(&shifted.0, []);
176 }
177 }
178 first = false;
179 }
180
181 let mut count = 0;
182 let mut polycube = Vec::with_capacity(Y.cubie_count());
183 solver.solve(|mut solution| {
184 // Print the solution, which consists of a set of 25 pentacubes.
185 print!("[");
186 while solution.next(&mut polycube) {
187 print!("[");
188 if let Some((&last, elements)) = polycube.split_last() {
189 for &cubie in elements {
190 print!("[{},{},{}],", cubie.0, cubie.1, cubie.2);
191 }
192 print!("[{},{},{}]", last.0, last.1, last.2);
193 }
194 print!("],");
195 }
196 println!("]");
197 count += 1;
198 });
199 println!("found {count} packings");
200}Sourcepub fn option_count(&self) -> usize
pub fn option_count(&self) -> usize
Returns the number of options in the solution.
Examples found in repository?
examples/langford_pairs.rs (line 58)
38fn main() {
39 let numbers = (1..=N).map(Item::Number);
40 let slots = (1..=2 * N).map(Item::Slot);
41 let items: Vec<_> = numbers.chain(slots).collect();
42
43 let mut solver: DlSolver<Item, ()> = DlSolver::new(&items, &[]);
44 for i in 1..=N {
45 // Optimization: half of the Langford pairs for a given value of $n$
46 // are the reverses of the others. Reduce the search space by placing
47 // the first 1 in position $1\le s_j<n$.
48 let first_slot_range = 1..if i == 1 { N } else { 2 * N - i };
49 for j in first_slot_range {
50 let k = i + j + 1;
51 let items = [Item::Number(i), Item::Slot(j), Item::Slot(k)];
52 solver.add_option(items, []);
53 }
54 }
55
56 let mut options = Vec::new();
57 solver.solve(|mut solution| {
58 assert_eq!(solution.option_count(), N);
59 // Convert the set of options into the corresponding placement.
60 let mut placement = [0usize; 2 * N];
61 while solution.next(&mut options) {
62 // Sort the items in `options` so we can perform pattern matching.
63 // Note that `Item` derives `Ord`, so item variants are ordered by
64 // their discriminants: numbers come before slots.
65 options.sort();
66 if let &[&Item::Number(i), &Item::Slot(j), &Item::Slot(k)] = &options[..] {
67 placement[j - 1] = i;
68 placement[k - 1] = i;
69 } else {
70 unreachable!("ordered option should match (number, slot, slot) pattern");
71 }
72 }
73 // Print the found Langford sequence, and its reverse.
74 println!("{:?}", placement);
75 placement.reverse();
76 println!("{:?}", placement);
77 });
78}Auto Trait Implementations§
impl<'s, 'i, I, C, S> Freeze for Solution<'s, 'i, I, C, S>
impl<'s, 'i, I, C, S> RefUnwindSafe for Solution<'s, 'i, I, C, S>
impl<'s, 'i, I, C, S> Send for Solution<'s, 'i, I, C, S>
impl<'s, 'i, I, C, S> Sync for Solution<'s, 'i, I, C, S>
impl<'s, 'i, I, C, S> Unpin for Solution<'s, 'i, I, C, S>where
C: Unpin,
impl<'s, 'i, I, C, S> !UnwindSafe for Solution<'s, 'i, I, C, S>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more