Practice problem
Longest Win Streak
MediumSolve in Python · graded against 2 sample tests and a hidden test set in your browser · Published
The Bug Report
The program reads several teams' seasons, one per line, where each season is a string of W and L
characters. For each team it prints the length of that team's longest unbroken run of wins. It runs, it
prints one number per team as it should, and some of those numbers are right.
Input that shows the problem
2
WWLWWWL
WWWWhat the program prints
0
3What it should print
3
3The first team won two, lost one, won three, then lost — a longest streak of 3. The program reports 0 for that team, as though it had never won a game, while getting the second team right. A team reported as 0 when its season contains five wins is not a rounding-level mistake; something is discarding what was already found.
Input Format
The input has t + 1 lines:
- Line 1: a single integer t, the number of teams.
- The next t lines: one season each, a string of
WandLcharacters with no spaces.
Output Format
Print t lines, one per team in the order the seasons were given. Each line holds a single integer: the
length of that team's longest run of consecutive wins, or 0 if that team never won.
How to Debug It
Two teams in and one of them is already wrong, so the first job is to find out which seasons fail rather
than why. Feed it a handful of one-team inputs and build a small table: W on its own, L on its own,
WWW, WWWLL, LLWW, WLWWLWWW. Write down what you expected and what you got for each. Do not read
the loop yet. Tables like this are how you turn "it is sometimes wrong" into a rule, and the rule here
falls out quickly: compare each season's last character against whether the answer was right.
With that rule in hand, pick the shortest failing season — WWWLL will do — and make the state visible.
Print current and best at the end of each pass through the loop, so you get five lines of trace for
five characters. Read the best column downwards. A running maximum should never go down, because a
maximum can only be beaten, never un-beaten. This one does go down, and the trace shows you exactly which
character it happens on.
That is the hypothesis: best is not accumulating across the whole season, it is being rebuilt from
scratch. Once you see where the rebuilding happens, the change is a single line moving a single statement,
with no arithmetic to rethink. Test it on the whole table you built, not just the case you were staring at
— in particular re-run LLWW, which was correct before your change and must still be correct afterwards,
and LLLL, which must still print 0.
What Was Wrong
The statement best = 0 was inside the loop:
for result in results:
best = 0
...
if current > best:
best = currentSo best is not the longest streak seen across the season at all. It is reset to 0 at the start of every
single character, which means the if current > best line two rows later is always comparing against 0
rather than against anything found earlier. Whatever it records is immediately thrown away when the next
character starts.
The consequence is that the value returned is simply current as it stood at the final character — the
streak still in progress when the season ended. For WWW that is 3, which is also the right answer, which
is why the second team looked fine. For WWLWWWL the season ends on a loss, so current has just been
reset to 0, best was reset to 0 as well, and 0 is what comes back. Both counters were zeroed at the same
moment, and the earlier three-win run had already been erased.
The fix is to initialise best once, beside current, where the season begins rather than where each
character begins:
current = 0
best = 0
for result in results:
...current legitimately resets, but only on a loss, and that reset is what makes it "the streak ending
here". best must not reset at all inside the season, because its whole job is to remember across the
characters that current forgets. Two counters in one loop with two different lifetimes is the pattern
worth carrying away: one is per-step, one is per-run, and putting them in the same scope makes them behave
identically when they should not.
Common Mistakes
- Returning
currentat the end instead of keeping a separate maximum. It gives the right answer for every season that finishes mid-streak and the wrong answer for every season that ends in a loss, which is precisely the failure in this report. The value you want is the best run anywhere in the season, not the run that happened to be alive when the input ran out. - Resetting
currenton every character rather than only on a loss. The opposite slip, and it caps every answer at 1: each win starts a brand new run of one instead of extending the run in progress. The reset belongs in theelsebranch alone. - Declaring both counters inside the per-team loop in
mainand reusing them across teams. Going too far the other way leaks one team's streak into the next team's answer. Each season is an independent question, which is why both counters live inside the function that answers it and are set fresh on every call.
Sample tests
Sample 1
Input
2 WWLWWWL WWW
Expected output
3 3
The first team's best run is the three wins in the middle (WWW between the two losses); the second team's whole season is one run of three.
Sample 2
Input
1 LLWW
Expected output
2
The best run is the two wins at the end. A season that ends mid-streak is, as it turns out, the case the broken program gets right.
Your solution
Run tries the first sample. Submit grades against every sample and the hidden tests. Your code is saved in this browser as you go.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.