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.

One flag, one pass
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 compares 2 < -1 and answers False; swap in index and it raises ValueError instead.
Tracking the phase
seen_b never 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