liao_generator/generator/
factor.rs1use rand::{seq::SliceRandom, thread_rng};
2
3use crate::rules::ff::new_ff_rule;
4use crate::rules::{bf::new_bf_rule, lf::new_lf_rule, nf::new_nf_rule, *};
5use crate::constants::{GenerateRules, GenerateFormula, FactorOptions, Operation};
6
7fn generate_with_rule(rules: GenerateRules, options: &FactorOptions) -> Option<u8> {
8 let mut rng = thread_rng();
9
10 let rule = match options.schema.operation {
11 Some(op) => match op {
12 Operation::Decrement => rules.decrement,
13 Operation::Increment => rules.increment,
14 },
15 None => panic!("Operation is not setted"),
16 };
17
18 if let Ok(numbers) = get_value_by_number(options.number, rule) {
19 let mut numbers = numbers.clone();
20
21 if let Some(forbidden_number) = options.forbidden_number {
22 numbers.retain(|&x| x != forbidden_number);
23 }
24
25 let force_formula = options.schema.force_formula;
26
27 if force_formula {
28 let force_numbers_stop = numbers.iter().position(|x| *x == 0);
29 let mut force_numbers: Vec<u8> = numbers
30 .clone()
31 .drain(0..force_numbers_stop.unwrap_or(0))
32 .collect();
33
34 force_numbers.retain(|x| *x != 0);
35
36 if force_numbers.len() > 0 {
37 let force_number = force_numbers.choose(&mut rng).unwrap();
38 return Some(*force_number);
39 }
40 }
41
42 let can_generate_zero = options.schema.can_generate_zero;
43
44 if !can_generate_zero {
45 numbers.retain(|&x| x != 0);
46 }
47
48 if numbers.is_empty() {
49 return None;
50 }
51
52 numbers.shuffle(&mut rng);
53
54 return Some(numbers[0]);
55 } else {
56 None
57 }
58}
59
60pub fn generate_factor(options: &FactorOptions) -> Option<u8> {
61 let rules: Option<GenerateRules> = match options.formula {
62 GenerateFormula::NF => Some(new_nf_rule()),
63 GenerateFormula::LF => Some(new_lf_rule()),
64 GenerateFormula::BF => Some(new_bf_rule()),
65 GenerateFormula::FF => Some(new_ff_rule()),
66 };
67
68 if let Some(rules) = rules {
69 return generate_with_rule(rules, &options);
70 }
71
72 None
73}