Ordered Character Check
An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- easy
- Seniority
- L6
- Asked in
- phData
Problem
An on-call engineer is reading a deploy log s, a string of 'A' (setup) and 'B' (serving) markers: does every setup step come before every serving step? A log that never reaches one of the phases, or is empty, still counts as in order.
Check if all As appear before all Bs.
Example 1
Input:
s = "AABB"
Output:
true
Example 2
Input:
s = "ABAB"
Output:
false
Worked solution and explanation
What this really is
This is a one-way door dressed up as a log check. Once the first 'B' shows up, the string has crossed into a phase it can never leave, and any 'A' after that is the violation. Most candidates write a loop. The ones who lose points reach for positions instead: s.rfind('A') < s.find('B'). It reads beautifully and passes 'AABB', 'ABAB' and 'BBAA'. Then a log that never reaches serving arrives: find('B') returns -1, the comparison says False, and a perfectly ordered 'AAA' is flagged as broken.
Build it as a door, not a comparison
Step 1: Walk the log once, left to right
The answer only depends on what came before each character, so one pass with a little memory is enough. No second pass, no positions.
Step 2: Remember whether the door has opened
Keep one flag, seen_b. A 'B' sets it. The log only has two kinds of marker, so any character that is not a 'B' is an 'A', and if seen_b is already set, that 'A' came too late: return False on the spot.
Step 3: Let absence fall through to True
If the loop finishes without tripping, nothing went backwards. 'AAA', 'BBB' and '' all reach the final return True with no special-case branch, which is exactly why the flag beats the index trick.
def ordered_character_check(s: str):
seen_b = False
for char in s:
if char == 'B':
seen_b = True
elif seen_b:
# Only 'A' reaches here, and it arrived after serving started.
return False
return True- Comparing positions
s.rfind('A') < s.find('B')assumes both markers exist. On 'AAA' it compares2 < -1and answers False; swap inindexand it raisesValueErrorinstead.- Tracking the phase
seen_bnever asks where a marker is, only whether serving has started. A missing phase simply never flips the flag, so the empty and single-phase logs come out True for free.
Common follow-up questions
- The log gains a third phase, 'C' (draining). How do you check A, then B, then C? (Generalizing one flag into a current-phase value that may only move forward.)
- How would you return the index of the first backwards step instead of a boolean? (Swapping the early `return False` for the position, and choosing a sentinel for the clean case.)
- What if the log arrives one marker at a time from a socket? (Recognizing the check is already online: `seen_b` is the only state to carry between events.)