Skip to content

Instantly share code, notes, and snippets.

@haze
Created January 7, 2021 23:27
Show Gist options
  • Save haze/f8ea1267bc2f18a46121311d6f8972dd to your computer and use it in GitHub Desktop.
Save haze/f8ea1267bc2f18a46121311d6f8972dd to your computer and use it in GitHub Desktop.
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