Skip to content

Instantly share code, notes, and snippets.

@maxnachlinger
Last active January 11, 2021 00:40
Show Gist options
  • Save maxnachlinger/b7eaef6e28b8810e144336967227b6fe to your computer and use it in GitHub Desktop.
Save maxnachlinger/b7eaef6e28b8810e144336967227b6fe to your computer and use it in GitHub Desktop.
#[derive(Clone, Debug, Default)]
pub struct WeightedInclusiveRange {
pub min: i32,
pub max: i32,
pub weight: i32,
}
impl WeightedInclusiveRange {
pub fn contains(&self, i: i32) -> bool {
i >= self.min && i <= self.max
}
}
// credit: https://softwareengineering.stackexchange.com/questions/187680/algorithm-for-dividing-a-range-into-ranges-and-then-finding-which-range-a-number
pub fn create_ranges(
min: &usize,
max: &usize,
number_of_ranges: &usize,
) -> Vec<WeightedInclusiveRange> {
let min_max_diff = max - min + 1;
let even_length = min_max_diff / number_of_ranges;
let mut bucket_sizes: Vec<usize> = vec![even_length; *number_of_ranges];
// if we've a reminder, distribute it across buckets
let mut even_length_remainder = min_max_diff % number_of_ranges;
let mut i = 0;
while even_length_remainder > 0 {
bucket_sizes[i] += 1;
even_length_remainder -= 1;
i = (i + 1) % number_of_ranges;
}
let mut ranges: Vec<WeightedInclusiveRange> =
vec![WeightedInclusiveRange::default(); *number_of_ranges];
i = 0;
let mut k = min.clone();
let local_max = max.clone();
while i < *number_of_ranges && k <= local_max {
ranges[i] = WeightedInclusiveRange {
min: k as i32,
max: (k + bucket_sizes[i] - 1) as i32,
weight: (number_of_ranges - i) as i32,
};
k = k.clone() + (bucket_sizes[i] as usize);
i += 1;
}
ranges
}
fn get_weight(ranges: &Vec<WeightedInclusiveRange>, i: i32) -> Option<i32> {
let found = ranges.iter().find(|r| r.contains(i));
found?;
Some(found?.weight)
}
fn main() {
let values = vec![
550, 625, 600, 550, 625, 600, 425, 500, 475, 525, 625, 600, 450, 325, 400, 425, 300,
];
let min = &values.iter().min().unwrap().clone();
let max = &values.iter().max().unwrap().clone();
let number_of_ranges: usize = 10;
let ranges = create_ranges(min, max, &number_of_ranges);
let weight = get_weight(&ranges, 350);
dbg!(&min, &max, &ranges, &weight);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment