Created
January 7, 2021 23:27
-
-
Save haze/f8ea1267bc2f18a46121311d6f8972dd to your computer and use it in GitHub Desktop.
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 std::collections::HashMap; | |
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | |
enum BaseRule { | |
Digit, | |
Upper, | |
Lower, | |
Special, | |
} | |
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | |
enum Rule { | |
Basic(BaseRule), | |
Multiple(Vec<BaseRule>), | |
} | |
#[derive(Debug)] | |
struct Ruleset(Vec<Rule>); | |
#[derive(Default, Clone, Debug, Eq, PartialEq)] | |
struct Scenario(HashMap<BaseRule, usize>); | |
impl Ruleset { | |
fn satisfies(&self, other: &Ruleset) -> bool { | |
let my_scenarios = self.scenarios(); | |
let their_scenarios = other.scenarios(); | |
// could optimize this with a trie based search / concat | |
my_scenarios.iter().any(|my_scenario| { | |
their_scenarios | |
.iter() | |
.any(|their_scenario| their_scenario == my_scenario) | |
}) | |
} | |
fn scenarios(&self) -> Vec<Scenario> { | |
let mut scenarios = Vec::new(); | |
let current_scenario = Scenario::default(); | |
if let Some(first_rule) = self.0.get(0) { | |
helper( | |
first_rule.clone(), | |
current_scenario, | |
0, | |
&self.0, | |
&mut scenarios, | |
); | |
} | |
scenarios | |
} | |
} | |
fn helper( | |
rule: Rule, | |
mut scenario: Scenario, | |
rule_idx: usize, | |
rule_set: &Vec<Rule>, | |
scenarios: &mut Vec<Scenario>, | |
) { | |
match rule { | |
Rule::Basic(base_rule) => { | |
*scenario.0.entry(base_rule).or_insert(0) += 1; | |
let rules_left = &rule_set[rule_idx + 1..]; | |
if rules_left.is_empty() { | |
scenarios.push(scenario); | |
} else { | |
for other_rule in rules_left { | |
helper( | |
other_rule.clone(), | |
scenario.clone(), | |
rule_idx + 1, | |
rule_set, | |
scenarios, | |
); | |
} | |
} | |
} | |
Rule::Multiple(rules) => { | |
for rule in rules { | |
helper( | |
Rule::Basic(rule), | |
scenario.clone(), | |
rule_idx, | |
rule_set, | |
scenarios, | |
); | |
} | |
} | |
} | |
} | |
fn main() { | |
let set_a = Ruleset(vec![ | |
Rule::Multiple(vec![BaseRule::Upper, BaseRule::Lower, BaseRule::Digit]), | |
Rule::Basic(BaseRule::Digit), | |
]); | |
let set_b = Ruleset(vec![ | |
Rule::Basic(BaseRule::Upper), | |
Rule::Multiple(vec![BaseRule::Special, BaseRule::Digit]), | |
]); | |
dbg!((&set_a, &set_b)); | |
dbg!(set_b.satisfies(&set_a)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment