# Everything That Repeats

> Say it once, then say how many times it stayed.

Canonical URL: <https://datadriven.io/problems/everything_that_repeats>

Domain: Python · Difficulty: easy · Seniority: L3

## Problem

A storage layer holds long status strings where the same character tends to repeat in stretches, and we want a compact form of `s`. Replace each stretch of one repeated character with that character followed by how many times it repeats in a row, and always write the count even when a character shows up just once.

## Worked solution and explanation

### What this really is

Strip the storage-compression costume and this is a single left-to-right scan that has to remember one thing: the character it is currently inside a run of, and how long that run has gotten. The whole problem lives in the transitions. Anyone can count; what separates candidates is handling the two moments where a run ENDS: when the next character differs, and when the string simply runs out. Miss the second one and your last group silently vanishes.

---

### The trap that bites

> **Consecutive, not total**
>
> The counts are about CONSECUTIVE runs, not totals. 'aabbaa' is three separate runs and encodes as 'a2b2a2'. A candidate who reaches for a frequency tally produces 'a4b2' and has quietly solved a different problem. The string's ORDER is the whole point.

---

### Break down the requirements

#### Step 1: Initialize tracking variables

Anchor on the first character with a count of 1. These two variables ARE the current run as you scan.

#### Step 2: Compare each character to its neighbor

From the second character on, compare to the previous one: same character means bump the count, a different one means the run just ended, so flush 'char + count' and reset count to 1.

#### Step 3: Flush the final run after the loop

The final run never meets a differing character to trigger its flush, so the loop alone leaves it unwritten. Append it explicitly after the loop. This is the single most-missed line.

---

### The solution

**Single-pass run-length encoding**

```python
def run_length_encode(s: str) -> str:
    if not s:
        return ""
    result = ""
    count = 1
    for i in range(1, len(s)):
        if s[i] == s[i - 1]:
            count += 1
        else:
            result += s[i - 1] + str(count)
            count = 1
    result += s[-1] + str(count)
    return result
```

> **Time and Space Complexity**
>
> **Time:** O(n) where n is the length of the string. Each character is visited exactly once.
> 
> **Space:** O(n) for the result string in the worst case (no consecutive duplicates).

> **Interviewers Watch For**
>
> Whether you handle the final run correctly. Many candidates forget to flush the last group after the loop exits, producing truncated output that passes the easy cases and fails the long ones.

> **Common Pitfall**
>
> Returning an empty string for single-character input. A string like `'a'` should encode to `'a1'`, not `''`. The explicit post-loop flush is exactly what saves this case.

---

## Common follow-up questions

- What if the encoded string is longer than the original? _(Tests awareness that RLE can expand data when runs are short; a real compressor would fall back to the original.)_
- How would you decode this encoding back to the original string? _(Tests the inverse operation: parsing digits then repeating characters.)_
- What changes if the input can contain digits? _(Tests delimiter design: digits in the payload make the format ambiguous without an escape or separator scheme.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/everything_that_repeats)
- [Python Interview Questions](https://datadriven.io/python-interview-questions)
- [Data Engineering Interview Prep Guide](https://datadriven.io/data-engineer-interview-prep)
- [Daily Challenge](https://datadriven.io/daily)

---

Source: DataDriven (https://datadriven.io). 100% free data engineering interview prep. Live code execution against Postgres 16, Python 3.11, and Spark sandboxes. No paywall, no premium tier, no signup gate.