Validate and Resolve Chained Decision Rules
PlaidSoftware Engineer · Technical ScreenLast updated
Determine if all rules in a chained decision rule set resolve to a terminal 'pass' outcome without cycles or missing references.
Problem Statement
You are building a rule engine for evaluating financial compliance. The system maintains a table of validation rules. Each rule is defined as a pair (rule_name, result):
rule_name: A unique identifier for the rule.result: The outcome of the rule, which can be:"pass": The rule succeeds."fail": The rule fails.- Another rule's name: The outcome of this rule delegates to the outcome of the referenced rule.
Write a function all_rules_pass(rules: list[tuple[str, str]]) -> bool that returns True if every rule in the table ultimately resolves to "pass". Return False if any rule:
- Resolves to
"fail", - Forms a circular dependency (cycle),
- References an unknown rule not present in the table.
Function Signature
def all_rules_pass(rules: list[tuple[str, str]]) -> bool:
pass
Constraints
1 <= len(rules) <= 10^5rule_nameis a non-empty string of alphanumeric characters (excluding"pass"and"fail").- All
rule_nameentries inrulesare distinct. resultis a non-empty string of alphanumeric characters.
Examples
Example 1
rules = [
("RuleA", "RuleB"),
("RuleB", "RuleC"),
("RuleC", "pass"),
("RuleD", "RuleC")
]
# Output: True
# Explanation: RuleA -> RuleB -> RuleC -> pass.
# RuleD -> RuleC -> pass. All rules resolve to "pass".
Example 2
rules = [
("KYC", "AML"),
("AML", "KYC"),
("Sanctions", "pass")
]
# Output: False
# Explanation: "KYC" and "AML" form an infinite cycle.
Example 3
rules = [
("CreditCheck", "IncomeCheck"),
("IncomeCheck", "fail")
]
# Output: False
# Explanation: Both rules resolve to "fail".
Example 4
rules = [
("Rule1", "Rule2"),
("Rule2", "UnknownRule")
]
# Output: False
# Explanation: "Rule2" references "UnknownRule", which is not defined.
Hints
Hint 1
Model the rules as a directed graph where each rule has at most one outgoing edge.
Hint 2
Use a three-state traversal (e.g., unvisited, visiting, visited) to detect cycles and identify missing references.
Hint 3
Memoize the resolved boolean status of each node so each rule is processed in O(1) amortized time.
Follow-up questions
- How would you modify the function to return a map of each rule to its specific termination status ('pass', 'fail', 'cycle', or 'missing_reference')?
- How would your approach adapt if rules supported boolean expressions (e.g., 'RuleA AND (RuleB OR RuleC)') instead of single delegations?
- In a production system where rules are dynamically updated by multiple services, how would you efficiently validate that an update does not introduce a cycle?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.