Last active
February 21, 2025 20:06
-
-
Save asterite/cbea91f23ec600be288bcc39b0a3d14e to your computer and use it in GitHub Desktop.
Generically choose a weight option
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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