some light optimisation
This commit is contained in:
parent
338888133c
commit
ec0dd29fa4
2 changed files with 45 additions and 9 deletions
31
src/lib.rs
31
src/lib.rs
|
|
@ -26,6 +26,12 @@ pub struct Adjacencies {
|
|||
}
|
||||
|
||||
impl Adjacencies {
|
||||
pub fn for_table(seats: &Seating) -> Self {
|
||||
let mut adj = Self::new(seats.amount);
|
||||
seats.get_adjacent(&mut adj);
|
||||
adj
|
||||
}
|
||||
|
||||
pub fn new(size: usize) -> Self {
|
||||
Adjacencies {
|
||||
amap: (0..size).map(|_| BitVec::from_elem(size, false)).collect(),
|
||||
|
|
@ -43,7 +49,7 @@ impl Adjacencies {
|
|||
fn is_disjoint(&mut self, other: &Adjacencies) -> bool {
|
||||
self.amap.iter_mut().enumerate().all(|(key, bitvec)| {
|
||||
bitvec.and(&other.amap[key]);
|
||||
!bitvec.any()
|
||||
bitvec.none()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -61,6 +67,21 @@ impl Adjacencies {
|
|||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn union(&self, other: &Adjacencies) -> Adjacencies {
|
||||
Adjacencies {
|
||||
amap: self
|
||||
.amap
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(key, bitset)| {
|
||||
let mut bc = bitset.clone();
|
||||
bc.or(&other.amap[key]);
|
||||
bc
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Adjacencies {
|
||||
|
|
@ -104,12 +125,10 @@ impl Display for Seating {
|
|||
|
||||
impl Seating {
|
||||
pub fn calc_alternatives(
|
||||
&self,
|
||||
size: usize,
|
||||
old_adjacencies: &Adjacencies,
|
||||
) -> impl Coroutine<Yield = Seating, Return = usize> {
|
||||
let mut old_adjacencies = Adjacencies::new(size);
|
||||
self.get_adjacent(&mut old_adjacencies);
|
||||
|
||||
let old_adjacencies = old_adjacencies.clone();
|
||||
#[coroutine]
|
||||
move || {
|
||||
let mut checked_locations = 0;
|
||||
|
|
@ -197,7 +216,7 @@ impl Seating {
|
|||
side[x] = Some(person);
|
||||
}
|
||||
|
||||
fn get_adjacent(&self, prev_adj: &mut Adjacencies) {
|
||||
pub fn get_adjacent(&self, prev_adj: &mut Adjacencies) {
|
||||
for (i, person) in self.people_top.iter().enumerate() {
|
||||
if let &Some(person) = person {
|
||||
assert!(
|
||||
|
|
|
|||
23
src/main.rs
23
src/main.rs
|
|
@ -1,26 +1,43 @@
|
|||
#![feature(coroutine_trait)]
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufWriter, Result, Write},
|
||||
ops::{Coroutine, CoroutineState},
|
||||
pin::Pin,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use shuffles::*;
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<()> {
|
||||
// let file = File::create("./valid_seatings")?;
|
||||
// let mut bf = BufWriter::new(file);
|
||||
|
||||
for size in 0..18 {
|
||||
let table = Seating::make_seating(size);
|
||||
println!("We have a table\n{table}");
|
||||
let mut corot = table.calc_alternatives(size);
|
||||
let mut old_adjacencies = Adjacencies::for_table(&table);
|
||||
let mut corot = Seating::calc_alternatives(size, &old_adjacencies);
|
||||
println!("searching size {size}");
|
||||
|
||||
let mut total = 0;
|
||||
let start = Instant::now();
|
||||
loop {
|
||||
match Pin::new(&mut corot).resume(()) {
|
||||
CoroutineState::Yielded(_val) => total += 1,
|
||||
CoroutineState::Yielded(val) => {
|
||||
// writeln!(bf, "Seating {} for size {} is \n{}", total, size, val)?;
|
||||
total += 1;
|
||||
}
|
||||
CoroutineState::Complete(total_checked) => {
|
||||
println!("checked {total_checked} in total to find {total} valid alternatives");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"finished size {size} in {:.03} sec",
|
||||
start.elapsed().as_secs_f64()
|
||||
)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue