Skip to content

S3Q2 · Fill Numbered Brackets in Text

⚡ Quick Reference

Type: Full I/O - string replacement with a running counter

Core idea: for each line, replace every [] with [n] where n is a global counter incrementing left to right, top to bottom.

n = int(input())
counter = 1
for _ in range(n):
    line = input()
    result = []
    i = 0
    while i < len(line):
        if line[i:i+2] == "[]":
            result.append(f"[{counter}]")
            counter += 1
            i += 2
        else:
            result.append(line[i])
            i += 1
    print("".join(result))

Key rules: - Replace [] (not [anything]) with [counter] - Counter is global across all lines - continues from where the previous line left off - All other characters remain unchanged


Problem Statement

Problem (I/O type)

Read n lines of text. Replace each [] with [1], [2], [3], … in left-to-right, top-to-bottom order.

Example:

Input
3
Programming[] is Good[]
The[] quick brown[] fox
jumps[] over the lazy[] dog[]
Output
Programming[1] is Good[2]
The[3] quick brown[4] fox
jumps[5] over the lazy[6] dog[7]

Understanding the approach

The simplest approach: use str.replace("[]", "[n]", 1) in a loop - replace one [] at a time, incrementing the counter.

line = "Programming[] is Good[]"
counter = 1

# First replacement:
line = line.replace("[]", f"[{counter}]", 1)  # "Programming[1] is Good[]"
counter = 2

# Second replacement:
line = line.replace("[]", f"[{counter}]", 1)  # "Programming[1] is Good[2]"
counter = 3

The count=1 argument to replace() replaces only the first occurrence each call.

str.replace(old, new, count)

The third argument limits how many replacements are made. replace("[]", "[n]", 1) replaces only the first [] found. Calling it in a loop with an incrementing counter handles all occurrences sequentially.


Tracing the example

Line 1: "Programming[] is Good[]"

Replace 1st []: "Programming[1] is Good[]"  → counter=2
Replace 1st []: "Programming[1] is Good[2]" → counter=3
No more [] → print

Line 2: "The[] quick brown[] fox" (counter starts at 3)

Replace 1st []: "The[3] quick brown[] fox"  → counter=4
Replace 1st []: "The[3] quick brown[4] fox" → counter=5

Line 3: "jumps[] over the lazy[] dog[]" (counter starts at 5)

[5], [6], [7] → "jumps[5] over the lazy[6] dog[7]"


Solution approaches

n = int(input())
counter = 1
for _ in range(n):
    line = input()
    while "[]" in line:
        line = line.replace("[]", f"[{counter}]", 1)
        counter += 1
    print(line)

Cleanest approach - while "[]" in line keeps replacing until none remain.

n = int(input())
counter = 1
for _ in range(n):
    line = input()
    result = []
    i = 0
    while i < len(line):
        if line[i:i+2] == "[]":
            result.append(f"[{counter}]")
            counter += 1
            i += 2
        else:
            result.append(line[i])
            i += 1
    print("".join(result))

Scans character by character - [] is a 2-char token, so skip 2 when matched.

import re

n = int(input())
counter = [1]   # mutable to allow modification inside lambda

def replace_bracket(match):
    result = f"[{counter[0]}]"
    counter[0] += 1
    return result

lines = [input() for _ in range(n)]
full_text = "\n".join(lines)
output = re.sub(r'\[\]', replace_bracket, full_text)
print(output)

re.sub with a callable replacement - the function is called once per match, incrementing the counter each time. Processes all lines at once.

import re
from itertools import count

n = int(input())
c = count(1)
lines = "\n".join(input() for _ in range(n))
print(re.sub(r'\[\]', lambda m: f"[{next(c)}]", lines))

itertools.count(1) is an infinite counter. next(c) advances it each time the lambda is called by re.sub. Most compact approach - one line of processing after reading input.


Key takeaways

01

str.replace(old, new, 1) for one-at-a-time replacement

The third argument count=1 limits to the first occurrence. Calling it in a while "[]" in line loop replaces each bracket sequentially with the correct number.

02

Global counter across lines

The counter must persist across all lines - initialise it before the outer loop and never reset it between lines. Line 2 continues from where line 1 left off.

03

re.sub with callable - powerful for sequential replacements

When the replacement depends on state (like a counter), pass a function to re.sub instead of a string. The function is called once per match, enabling stateful replacements cleanly.