Implement a Longest-Match Tokenizer
Company: Anthropic
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Onsite
# Implement a Longest-Match Tokenizer
The source reports longest matching, unknown-token handling, and an optional unknown-merging extension. The exact function flag and output payload below are a deterministic practice contract.
Implement:
```python
def tokenize(
text: str,
vocabulary: dict[str, int],
unknown_id: int,
coalesce_unknowns: bool = False,
) -> list[tuple[int, str]]:
...
```
Scan `text` from left to right. At each position, emit the longest vocabulary token that matches there as `(token_id, exact_token_text)`. If no token matches, consume exactly one Unicode code point as unknown.
- With the default `coalesce_unknowns=False`, emit one `(unknown_id, character)` tuple per unmatched code point.
- With `coalesce_unknowns=True`, merge each maximal consecutive run of unmatched code points into one `(unknown_id, substring)` tuple. A recognized token always ends an unknown run.
Vocabulary keys are unique because the input is a dictionary, so two different equal-length strings cannot both match the same position. Token IDs may repeat and `unknown_id` may equal a vocabulary ID; the consumed-text field keeps the output unambiguous. Matching is case-sensitive. Concatenating the second field of every result must reproduce `text` exactly.
## Constraints and Errors
- `text` is a string and every vocabulary key is a string.
- Vocabulary tokens must be nonempty. An empty token or a non-Boolean `coalesce_unknowns` raises `ValueError` before producing output.
- Empty input returns `[]`; an empty vocabulary makes the whole nonempty input unknown according to the selected mode.
- Operate on Python Unicode code points, not encoded bytes.
Discuss a direct vocabulary scan and a trie-based implementation. Test overlapping tokens, an entire unknown string in both modes, recognized text between unknown runs, duplicate token IDs, an unknown ID shared with a known token, and empty input.
Quick Answer: Implement a case-sensitive longest-match tokenizer that emits token IDs with the exact consumed text. Support per-character or coalesced unknown runs, validate the vocabulary, preserve Unicode code points, and compare direct matching with a trie.
Scan text left to right, emitting the longest vocabulary token at each position or unknown code points, optionally coalescing consecutive unknowns.
Constraints
- Vocabulary tokens are nonempty strings
- Matching is case-sensitive over Unicode code points
- Concatenated consumed text must reproduce the input
Examples
Input: {'text': '', 'vocabulary': {'a': 1}, 'unknown_id': -1, 'coalesce_unknowns': False}
Expected Output: []
Explanation: Empty input emits no tokens.
Input: {'text': 'abcd', 'vocabulary': {'a': 1, 'ab': 2, 'bc': 3, 'd': 4}, 'unknown_id': -1, 'coalesce_unknowns': False}
Expected Output: [(2, 'ab'), (-1, 'c'), (4, 'd')]
Explanation: The longest prefix wins before a one-character unknown.
Hints
- A trie records every vocabulary prefix.
- Remember the last terminal node reached while walking from a text position.