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