def before_first_stop_word(text: str, stop_words: Iterable[str]) -> str:
Perplexity's stop-word question, from three reports, all posted in October 2025. Two are phone screens (one a video phone screen); the third gives the problem and its streaming follow-up without naming the round. No report gives an outcome. One report says the round comes in several parts and describes two; that poster guesses later parts might add an optimization such as a trie, which no report confirms. No starter code was captured, so every name below is ours.
Given a string and a vocabulary of stop words (one report says a list), return the part of the string before the first stop word. One report says a stop word can appear anywhere.
What the tests call (our setup — ask your interviewer)
def before_first_stop_word(text: str, stop_words: list[str]) -> str: ... # Part 1
def stream_before_first_stop_word(chunks, stop_words: list[str]): ... # Part 2, a generator
def collect_stream(chunks, stop_words: list[str]) -> str: ... # given: joins what your generator yields
stop_words is a list of strings. Our reading of "anywhere": a stop word matches as a substring, even inside a longer word, so stop in abcstopdef gives abc. "First" means the occurrence that starts earliest in the text, whatever the list order. Matching is case-sensitive, and with no stop word in the text the answer is the whole text. These conventions are ours: ask.
Part 1 — text before the first stop word
before_first_stop_word(text, stop_words) -> str.From candidate reports: three reports, all posted in October 2025. One phone-screen report describes the round as several parts and gives two: the in-memory version, then input too large to take out at once, read piece by piece with a Python generator. That poster advises not optimizing the first part ("the simpler the better", confirming with the interviewer), says they wrote the generator slowly for lack of fluency, and guesses that later parts might optimize with a trie; no report confirms a third part. A video phone-screen report calls it the stop-words question already on the forum and says the interviewer then asked how to optimize; asked what was discussed, the poster says they proposed, for their own code, using the longest stop word's length to reduce how much of the string must be buffered. The third report gives the problem with a list of stop words and the follow-up of a stream that cannot be held in memory, with no round or outcome. No report gives an outcome; the video-screen poster was looking for partners to prepare an onsite. A commenter on that thread had a one-hour phone screen of their own; this question's round length is not reported.
Our notes: the tests grade that Part 2 stops reading soon after the stop word arrives, not how much it holds; a solution that keeps every character it has read still passes. Overlapping stop words of different lengths (xyz and y over x, y, z) are not graded: the reference answers as Part 1 would, by earliest start, and a solution that returns on the first complete match is also reasonable.
Perplexity's stop-word question, from three reports, all posted in October 2025. Two are phone screens (one a video phone screen); the third gives the problem and its streaming follow-up without naming the round. No report gives an outcome. One report says the round comes in several parts and describes two; that poster guesses later parts might add an optimization such as a trie, which no report confirms. No starter code was captured, so every name below is ours.
Given a string and a vocabulary of stop words (one report says a list), return the part of the string before the first stop word. One report says a stop word can appear anywhere.
What the tests call (our setup — ask your interviewer)
def before_first_stop_word(text: str, stop_words: list[str]) -> str: ... # Part 1
def stream_before_first_stop_word(chunks, stop_words: list[str]): ... # Part 2, a generator
def collect_stream(chunks, stop_words: list[str]) -> str: ... # given: joins what your generator yields
stop_words is a list of strings. Our reading of "anywhere": a stop word matches as a substring, even inside a longer word, so stop in abcstopdef gives abc. "First" means the occurrence that starts earliest in the text, whatever the list order. Matching is case-sensitive, and with no stop word in the text the answer is the whole text. These conventions are ours: ask.
Part 1 — text before the first stop word
before_first_stop_word(text, stop_words) -> str.Part 2 — stream the input through a generator
stream_before_first_stop_word(chunks, stop_words) as a Python generator over the chunks that yields the text before the first stop word, in as many pieces as you like.chunks is a list or an iterator of strings (our setup). The tests join what you yield with the given collect_stream(chunks, stop_words), and the joined result must equal the Part 1 answer for the joined chunks. They also check that the function returns an iterator, and that it stops reading chunks soon after the stop word has arrived instead of reading the whole input first.xyz and y arriving as x, y, z. Whether the answer is the text before the earlier-starting word or before the first word to finish arriving is not reported and not graded: ask which one the interviewer wants.yield first.Now the input is too large to read at once — process it as a stream of chunks with a generator.
How would you optimize it?
Common mistakes: Optimizing Part 1 before it works: one candidate advises against optimizing it at all (the simpler the better, it saves time) and says to confirm the scope with the interviewer.; Being unfamiliar with Python generator semantics: the candidate who said so wrote the chunked-input Part 2 slowly and suggests practising first.
Interviewer hints: In one round the interviewer asked how to optimize the solution. The candidate's answer, for their own code, used the longest stop word's length, max(stop_word_len), to reduce how much of the string has to be buffered.
What candidates report: One candidate guesses that later parts might optimize the lookup with a trie; no report confirms a third part.
Optimization (our analysis): a stop word that straddles a chunk boundary has at most max_len − 1 characters in the earlier chunk, so keeping that many trailing characters between chunks is enough. Memory is then O(chunk + max_len), whatever the input size. Clarify: whole-word or substring matching, since it changes the scan.