some light optimisation

This commit is contained in:
Noa Aarts 2025-12-12 21:05:29 +01:00
parent 338888133c
commit ec0dd29fa4
Signed by: noa
GPG key ID: 1850932741EFF672
2 changed files with 45 additions and 9 deletions

View file

@ -26,6 +26,12 @@ pub struct Adjacencies {
} }
impl 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 { pub fn new(size: usize) -> Self {
Adjacencies { Adjacencies {
amap: (0..size).map(|_| BitVec::from_elem(size, false)).collect(), amap: (0..size).map(|_| BitVec::from_elem(size, false)).collect(),
@ -43,7 +49,7 @@ impl Adjacencies {
fn is_disjoint(&mut self, other: &Adjacencies) -> bool { fn is_disjoint(&mut self, other: &Adjacencies) -> bool {
self.amap.iter_mut().enumerate().all(|(key, bitvec)| { self.amap.iter_mut().enumerate().all(|(key, bitvec)| {
bitvec.and(&other.amap[key]); bitvec.and(&other.amap[key]);
!bitvec.any() bitvec.none()
}) })
} }
@ -61,6 +67,21 @@ impl Adjacencies {
.collect(), .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 { impl Display for Adjacencies {
@ -104,12 +125,10 @@ impl Display for Seating {
impl Seating { impl Seating {
pub fn calc_alternatives( pub fn calc_alternatives(
&self,
size: usize, size: usize,
old_adjacencies: &Adjacencies,
) -> impl Coroutine<Yield = Seating, Return = usize> { ) -> impl Coroutine<Yield = Seating, Return = usize> {
let mut old_adjacencies = Adjacencies::new(size); let old_adjacencies = old_adjacencies.clone();
self.get_adjacent(&mut old_adjacencies);
#[coroutine] #[coroutine]
move || { move || {
let mut checked_locations = 0; let mut checked_locations = 0;
@ -197,7 +216,7 @@ impl Seating {
side[x] = Some(person); 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() { for (i, person) in self.people_top.iter().enumerate() {
if let &Some(person) = person { if let &Some(person) = person {
assert!( assert!(

View file

@ -1,26 +1,43 @@
#![feature(coroutine_trait)] #![feature(coroutine_trait)]
use std::{ use std::{
fs::File,
io::{BufWriter, Result, Write},
ops::{Coroutine, CoroutineState}, ops::{Coroutine, CoroutineState},
pin::Pin, pin::Pin,
time::Instant,
}; };
use shuffles::*; use shuffles::*;
fn main() { fn main() -> Result<()> {
// let file = File::create("./valid_seatings")?;
// let mut bf = BufWriter::new(file);
for size in 0..18 { for size in 0..18 {
let table = Seating::make_seating(size); let table = Seating::make_seating(size);
println!("We have a table\n{table}"); 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}"); println!("searching size {size}");
let mut total = 0; let mut total = 0;
let start = Instant::now();
loop { loop {
match Pin::new(&mut corot).resume(()) { 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) => { CoroutineState::Complete(total_checked) => {
println!("checked {total_checked} in total to find {total} valid alternatives"); println!("checked {total_checked} in total to find {total} valid alternatives");
break; break;
} }
} }
} }
println!(
"finished size {size} in {:.03} sec",
start.elapsed().as_secs_f64()
)
} }
Ok(())
} }