Skip to content

Instantly share code, notes, and snippets.

@BlueZeeKing
Created May 30, 2024 18:07
Show Gist options
  • Save BlueZeeKing/79e6ba72bda333bfa934889211168b88 to your computer and use it in GitHub Desktop.
Save BlueZeeKing/79e6ba72bda333bfa934889211168b88 to your computer and use it in GitHub Desktop.
use std::ops::Range;
#[derive(Debug, Clone)]
pub struct Event {
initial_index: usize,
placement_index: u32,
size_at_calculation: u32,
range: Range<u32>,
}
// Pass result into `compute_widths`
pub fn slice_calendar(events: impl Iterator<Item = Range<u32>>) -> Vec<Event> {
let mut slices = Vec::new();
events
.enumerate()
.map(|(initial_index, event)| {
if slices.is_empty() {
slices.push(Some(event.clone()));
return Event {
initial_index,
placement_index: 0,
size_at_calculation: slices.len() as u32,
range: event,
};
}
for slice in slices.iter_mut().filter(|val| val.is_some()) {
if slice.as_ref().unwrap().end <= event.start {
*slice = None;
}
}
for i in (0..slices.len()).rev() {
if slices[i].is_some() {
break;
}
slices.remove(i);
}
let slice = slices
.iter_mut()
.enumerate()
.find(|(_, slice)| slice.is_none());
if let Some((idx, slice)) = slice {
*slice = Some(event.clone());
Event {
initial_index,
placement_index: idx as u32,
size_at_calculation: slices.len() as u32,
range: event,
}
} else {
slices.push(Some(event.clone()));
Event {
initial_index,
placement_index: slices.len() as u32 - 1,
size_at_calculation: slices.len() as u32,
range: event,
}
}
})
.collect()
}
pub fn compute_widths(mut values: Vec<Event>) -> Vec<(u32, u32)> {
let mut response = values
.iter()
.map(|event| (event.placement_index, event.size_at_calculation))
.collect::<Vec<_>>();
values.sort_by(|a, b| b.size_at_calculation.cmp(&a.size_at_calculation));
for value in &values {
for inner in &values {
if does_overlap(&value.range, &inner.range) {
response[inner.initial_index].1 = response[value.initial_index]
.1
.max(response[inner.initial_index].1);
}
}
}
response
}
fn does_overlap(a: &Range<u32>, b: &Range<u32>) -> bool {
(a.start <= b.start && a.end > b.start) || (b.start <= a.start && b.end > a.start)
}
#[cfg(test)]
mod tests {
use crate::does_overlap;
#[test]
fn overlap() {
assert!(does_overlap(&(1..3), &(2..5)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment