Katkat

Evaluate Dependent Variable Assignments

Applied IntuitionSoftware Engineer · Technical Screen

Last updated

Evaluate a list of variable assignment statements where variable values can depend on variables defined later in the input. The problem tests expression parsing, cycle detection, dependency resolution via topological ordering or memoized depth-first search, and deep recursion handling.

Evaluate Dependent Variable Assignments

You are building a lightweight configuration evaluator for an autonomous simulation engine. You are given a list of assignment statements. Each statement assigns an integer value or an arithmetic expression to a unique variable name.

Crucially, expressions may reference variables defined later in the input list. If all references are valid and contain no circular dependencies, evaluate the integer value of every variable.

Requirements

Each statement is a string formatted as: " = "

  • `` is an alphanumeric identifier (e.g., "x", "steer_gain").
  • `` contains non-negative integer literals, variable identifiers, and the binary operators +, -, and *. Parentheses ( and ) may be present.
  • Whitespace around tokens should be ignored.
  • If there is a circular dependency (e.g., a = b + 1 and b = a * 2) or an undefined variable reference, return an empty list [].
  • Otherwise, return a list of tuples (var_name, evaluated_value) in the exact order the variables were introduced in the input.

Function Signature

def evaluate_assignments(statements: list[str]) -> list[tuple[str, int]]:
    pass

Constraints

  • 1 <= len(statements) <= 2,000
  • Each variable identifier consists of 1 to 30 ASCII alphanumeric characters and underscores.
  • No variable is defined more than once on the left-hand side.
  • Expressions contain at most 50 tokens.
  • Dependency chains can be up to 2,000 variables deep.
  • Values fit within standard 64-bit signed integers (or arbitrary-precision integers in Python).
  • Division by zero is not tested (only +, -, * are supported).

Examples

Example 1:

statements = [
    "speed = base_speed * 2",
    "accel = 5",
    "base_speed = accel + 10"
]
# base_speed = 5 + 10 = 15
# speed = 15 * 2 = 30
# accel = 5

output = evaluate_assignments(statements)
# Output: [("speed", 30), ("accel", 5), ("base_speed", 15)]

Example 2:

statements = [
    "x = y + 1",
    "y = x * 2"
]

output = evaluate_assignments(statements)
# Output: [] (circular dependency detected)

Example 3:

statements = [
    "a = b + 3",
    "c = 10"
]

output = evaluate_assignments(statements)
# Output: [] (variable 'b' is never defined)

Hints

Hint 1

Separate the task into two stages: first parse each expression into its referenced variables (dependency edges), then resolve the evaluation order.

Hint 2

Use a directed graph where an edge exists from variable U to variable V if U's expression depends on V; detect cycles using 3-color DFS or Kahn's algorithm.

Hint 3

Because dependency chains can be thousands of levels deep, either evaluate nodes in post-order from topological sort iteratively or increase the recursion limit to avoid stack overflow.

Follow-up questions

  • How would you extend this evaluator to support integer division and detect division-by-zero errors at evaluation time?
  • If the number of statements scaled to 1,000,000 across multiple machines, how would you design the distributed dependency resolution?
  • How would your approach change if variables could be conditionally defined or updated multiple times sequentially?