Validate a Train Consist Against Hazardous-Material Placement Rules

Read the full interview experience this question came from →

Quick Overview

Write validation logic that checks a train's car order and hazardous-material placement against a set of placement rules and reports every violation with a detailed explanation of the rule, cars and positions involved. It tests input modeling, rule design that extends to new rules, careful position arithmetic and clear error reporting.

Validate a Train Consist Against Hazardous-Material Placement Rules

Company: Bnsf

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

Write the validation logic for a train's car arrangement. The inputs are a set of placement rules, the order of the cars in the train (the consist, listed front to back), and the hazardous-material information that says which cars carry which hazardous materials. Check the arrangement against every rule and decide whether it is valid. When it is not, output detailed error messages that explain each violation: which rule was broken, which cars and positions are involved, and why. The report does not give the interviewer's actual rules or input format. To practice, use the illustrative input below and treat its rule types and parameters as placeholders: your design should not depend on these particular rules. ```json { "rules": [ {"id": "R1", "type": "buffer_from_locomotive", "min_cars_between": 2}, {"id": "R2", "type": "incompatible_adjacent", "classes": ["flammable_gas", "oxidizer"]}, {"id": "R3", "type": "not_last"} ], "consist": [ {"car_id": "L1", "kind": "locomotive"}, {"car_id": "B1", "kind": "boxcar"}, {"car_id": "T1", "kind": "tank"}, {"car_id": "B2", "kind": "boxcar"}, {"car_id": "T2", "kind": "tank"}, {"car_id": "T3", "kind": "tank"}, {"car_id": "B3", "kind": "boxcar"} ], "hazmat": {"T1": "explosive", "T2": "flammable_gas", "T3": "oxidizer"} } ``` Positions are 1-based in consist order. The three illustrative rules mean: - `R1` (`buffer_from_locomotive`): a car carrying hazardous material must have at least `min_cars_between` cars between it and the nearest locomotive. - `R2` (`incompatible_adjacent`): a car carrying one of the two listed classes must not be directly next to a car carrying the other. - `R3` (`not_last`): the last car of the train must not carry hazardous material. For this input, a report in this format would be: ```text INVALID (2 violations) R1 buffer_from_locomotive: car T1 (explosive) at position 3 has 1 car(s) between it and locomotive L1 at position 1; at least 2 are required R2 incompatible_adjacent: car T2 (flammable_gas) at position 5 is next to car T3 (oxidizer) at position 6; flammable_gas and oxidizer must not be adjacent ``` ### Clarifying Questions - What exactly are the rules, and are they fixed in code or supplied as data that can change between calls? - Is the consist always listed front to back, can a train have several locomotives (at the front, in the middle or at the rear), and do locomotives count as cars when measuring distances? - Do the car order and the hazardous-material information always agree, or must the validator report a hazardous-material record for a car that is not in the train, or a car listed twice? - Should the validator report every violation or stop at the first one, and in what order should the messages appear? - Who reads the output: a person preparing the train, another program, or both? ### Part 1 — Check the arrangement against every rule Join the consist with the hazardous-material information and evaluate every rule over the whole train, collecting all violations rather than stopping at the first. ```hint One view for every rule Think about which facts each rule needs about a car, such as its position, its kind, its hazard class and where the nearest locomotive is, and work them out once before any rule runs. ``` #### What This Part Should Cover - Joining the two inputs, and detecting inconsistent input such as duplicate cars or hazardous-material records for cars that are not in the train - One check per rule type, with correct position arithmetic at the boundaries: the first and last cars, and trains with several locomotives - Rules represented so that a new rule type can be added without rewriting the validator ### Part 2 — Explain every violation Turn the violations into detailed error messages, and report malformed or inconsistent input separately from rule violations. ```hint Messages someone can act on Ask what a person fixing the train needs from each message: the rule, the cars and where they sit, and what the rule required compared with what was found. ``` #### What This Part Should Cover - A structured violation record, kept separate from the text it is rendered into - A deterministic order for the messages - Tests that pin a valid train, each kind of violation and each kind of input error ### What a Strong Answer Covers - Clarifies the real rules and input format before coding, and states the assumptions it makes - Separates rule definitions, which are data, from the evaluation engine - Treats malformed input as errors distinct from rule violations - Near-linear evaluation per rule, with the complexity stated - Working, tested code within the interview time, delivered incrementally so that a partial solution still runs ### Follow-up Questions - A new rule arrives: a car carrying hazardous material must not be next to a car carrying a specific kind of load. How much code changes? - How would you suggest a valid rearrangement instead of only rejecting an invalid one? - Rule sets are versioned and can differ by route. How do you pick the right set and record which version approved a train? - The rule data itself may be wrong, for example a class listed as incompatible with itself or a negative distance. How do you validate the rules?

Overview: Write validation logic that checks a train's car order and hazardous-material placement against a set of placement rules and reports every violation with a detailed explanation of the rule, cars and positions involved. It tests input modeling, rule design that extends to new rules, careful position arithmetic and clear error reporting.

Read the full Bnsf Software Engineer interview experience this question came from

Bnsf logo
Bnsf
Oct 25, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

Write the validation logic for a train's car arrangement. The inputs are a set of placement rules, the order of the cars in the train (the consist, listed front to back), and the hazardous-material information that says which cars carry which hazardous materials. Check the arrangement against every rule and decide whether it is valid. When it is not, output detailed error messages that explain each violation: which rule was broken, which cars and positions are involved, and why.

The report does not give the interviewer's actual rules or input format. To practice, use the illustrative input below and treat its rule types and parameters as placeholders: your design should not depend on these particular rules.

{
  "rules": [
    {"id": "R1", "type": "buffer_from_locomotive", "min_cars_between": 2},
    {"id": "R2", "type": "incompatible_adjacent", "classes": ["flammable_gas", "oxidizer"]},
    {"id": "R3", "type": "not_last"}
  ],
  "consist": [
    {"car_id": "L1", "kind": "locomotive"},
    {"car_id": "B1", "kind": "boxcar"},
    {"car_id": "T1", "kind": "tank"},
    {"car_id": "B2", "kind": "boxcar"},
    {"car_id": "T2", "kind": "tank"},
    {"car_id": "T3", "kind": "tank"},
    {"car_id": "B3", "kind": "boxcar"}
  ],
  "hazmat": {"T1": "explosive", "T2": "flammable_gas", "T3": "oxidizer"}
}

Positions are 1-based in consist order. The three illustrative rules mean:

  • R1 ( buffer_from_locomotive ): a car carrying hazardous material must have at least min_cars_between cars between it and the nearest locomotive.
  • R2 ( incompatible_adjacent ): a car carrying one of the two listed classes must not be directly next to a car carrying the other.
  • R3 ( not_last ): the last car of the train must not carry hazardous material.

For this input, a report in this format would be:

INVALID (2 violations)
R1 buffer_from_locomotive: car T1 (explosive) at position 3 has 1 car(s) between it and locomotive L1 at position 1; at least 2 are required
R2 incompatible_adjacent: car T2 (flammable_gas) at position 5 is next to car T3 (oxidizer) at position 6; flammable_gas and oxidizer must not be adjacent

Clarifying Questions Guidance

  • What exactly are the rules, and are they fixed in code or supplied as data that can change between calls?
  • Is the consist always listed front to back, can a train have several locomotives (at the front, in the middle or at the rear), and do locomotives count as cars when measuring distances?
  • Do the car order and the hazardous-material information always agree, or must the validator report a hazardous-material record for a car that is not in the train, or a car listed twice?
  • Should the validator report every violation or stop at the first one, and in what order should the messages appear?
  • Who reads the output: a person preparing the train, another program, or both?

Part 1 — Check the arrangement against every rule

Join the consist with the hazardous-material information and evaluate every rule over the whole train, collecting all violations rather than stopping at the first.

What This Part Should Cover Guidance

  • Joining the two inputs, and detecting inconsistent input such as duplicate cars or hazardous-material records for cars that are not in the train
  • One check per rule type, with correct position arithmetic at the boundaries: the first and last cars, and trains with several locomotives
  • Rules represented so that a new rule type can be added without rewriting the validator

Part 2 — Explain every violation

Turn the violations into detailed error messages, and report malformed or inconsistent input separately from rule violations.

What This Part Should Cover Guidance

  • A structured violation record, kept separate from the text it is rendered into
  • A deterministic order for the messages
  • Tests that pin a valid train, each kind of violation and each kind of input error

What a Strong Answer Covers Guidance

  • Clarifies the real rules and input format before coding, and states the assumptions it makes
  • Separates rule definitions, which are data, from the evaluation engine
  • Treats malformed input as errors distinct from rule violations
  • Near-linear evaluation per rule, with the complexity stated
  • Working, tested code within the interview time, delivered incrementally so that a partial solution still runs

Follow-up Questions Guidance

  • A new rule arrives: a car carrying hazardous material must not be next to a car carrying a specific kind of load. How much code changes?
  • How would you suggest a valid rearrangement instead of only rejecting an invalid one?
  • Rule sets are versioned and can differ by route. How do you pick the right set and record which version approved a train?
  • The rule data itself may be wrong, for example a class listed as incompatible with itself or a negative distance. How do you validate the rules?