Skip to content

Instantly share code, notes, and snippets.

@asterite
Last active February 21, 2025 20:06
Show Gist options
  • Save asterite/cbea91f23ec600be288bcc39b0a3d14e to your computer and use it in GitHub Desktop.
Save asterite/cbea91f23ec600be288bcc39b0a3d14e to your computer and use it in GitHub Desktop.
Generically choose a weight option
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;
pub struct Config<T, const N: usize> {
pub options_with_weights: [(T, usize); N],
pub total_weight: usize,
}
impl<T: Copy, const N: usize> Config<T, N> {
pub const fn new(options_with_weights: [(T, usize); N]) -> Self {
let mut total_weight = 0;
let mut i = 0;
while i < options_with_weights.len() {
total_weight += options_with_weights[i].1;
i += 1;
}
Self {
options_with_weights,
total_weight,
}
}
pub fn select(&self, prng: &mut XorShiftRng) -> T {
let mut selector = prng.gen_range(0..self.total_weight);
for (option, weight) in &self.options_with_weights {
if selector < *weight {
return *option;
}
selector -= weight;
}
unreachable!("Should have returned by now")
}
}
pub const CONFIG: Config<Options, 4> = Config::new([
(Options::Addition, 1),
(Options::Subtraction, 2),
(Options::Multiplication, 3),
(Options::Division, 4),
]);
#[derive(Copy, Clone, Debug)]
pub enum Options {
Addition,
Subtraction,
Multiplication,
Division,
}
fn main() {
let mut rng = XorShiftRng::from_seed([0; 16]);
let option = CONFIG.select(&mut rng);
dbg!(option);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment