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 {
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!(

View file

@ -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(())
}