Clean and Validate Usernames
User-supplied username strings often arrive with leading or trailing noise — symbols, punctuation, spaces — before the actual username. Your job is to extract the username by trimming the invalid edges, then validate what remains.
Implement extract_valid_usernames(raw_inputs) using a two-pointer approach: a left pointer that advances inward past any leading invalid characters, and a right pointer that advances inward past any trailing invalid characters. The candidate username is everything between the two pointers.
A valid username contains only letters (a–z, A–Z), digits (0–9), and underscores, and is between 3 and 20 characters long (inclusive). Any character in the middle that is not in that set invalidates the entire candidate.
- Implement
extract_valid_usernames(raw_inputs: list[str]) -> list[str]inmain.py. - Use two pointers to strip leading and trailing characters that are not letters, digits, or underscores.
- A candidate is valid only if every character in it is a letter, digit, or underscore.
- A candidate is valid only if its length is between 3 and 20 characters (inclusive).
- Return valid extracted usernames in their original order. Inputs that yield no valid candidate are excluded.
- An empty input list returns an empty list.
raw_inputs = ["@alice_99!", " bob ", "@ab!"]
["alice_99", "bob"]
@alice_99! → trim @ and ! → "alice_99" (8 chars, all valid). " bob " → trim spaces → "bob" (3 chars, valid). @ab! → trim → "ab" (2 chars) — too short, excluded.
raw_inputs = ["hello world", "alice-bob", "valid_name"]
["valid_name"]
"hello world" has a space in the middle — not a valid character. "alice-bob" has a hyphen in the middle. "valid_name" passes all checks.
raw_inputs = ["@#$%", "", " "]
[]
All inputs yield empty or all-invalid candidates after trimming.
- Input strings may contain any printable characters.
raw_inputsmay be empty.- Preserve the order of valid usernames as they appeared in the input.
The current approach trims edges and then validates the middle. Could you combine those two phases into a single pass with a different pointer strategy?