Sign Shop Letter Blocks

MediumgreedyAlso known as Greedy Longest-Match Tokenizer

A sign shop builds shop-front lettering from pre-cut wooden blocks. Besides single letters, it keeps blocks for common letter groups like th, ing and bake, because one block is quicker to mount than four. The rule on the workbench: reading left to right, always grab the longest block that fits the next letters exactly. If no group fits, use a single letter.

Language models read text the same way. Before a model sees anything, a tokenizer cuts the text into pieces from a fixed vocabulary, and some tokenizers use this same longest-match-first rule. That is why a common word is often one token while a rare word breaks into several.

Your task

Write tokenize(text, pieces). Start at the first letter. At each position, find the longest string in pieces that appears in text starting exactly at that position. Add it to the result and move past it. If no piece matches, add the single letter at that position and move one step.

Return the list of tokens in order. Joined together they must spell text. An empty text gives an empty list.

tokenize(text: string, pieces: string[]) → string[]

Examples

Example 1
Input
text = "bakery"
pieces = ["ba", "bake", "ry", "er", "y"]
Output
["bake", "ry"]
Why

At position 0 both "ba" and "bake" fit; take the longer, "bake". At position 4, "ry" fits ("er" does not start there). The text is used up: ["bake", "ry"].

Example 2
Input
text = "thinking"
pieces = ["th", "in", "ink", "ing", "king"]
Output
["th", "ink", "ing"]
Why

"th" at 0. At 2, "in" and "ink" fit, take "ink". At 5, "ing" fits. Result ["th", "ink", "ing"]. Notice greedy does not look ahead: it never considers "in" + "king", even though that would also work.

Example 3
Input
text = "zoo"
pieces = ["oo", "bake"]
Output
["z", "oo"]
Why

No piece starts with "z", so it becomes a single-letter token. Then "oo" fits. Result ["z", "oo"].

Constraints

  • 0 ≤ text.length ≤ 10,000
  • 0 ≤ pieces.length ≤ 1,000
  • 1 ≤ pieces[i].length ≤ 20
  • text and pieces use lowercase letters a to z only. pieces may contain repeats.
Start with brute force

At every position, loop over all the pieces and check whether each one starts there, keeping the longest. With 10,000 letters and 1,000 pieces of up to 20 letters, that is up to 200 million character comparisons.

Most of that work is wasted: at any position only about 20 lengths are possible, and a set can say whether a given chunk is a piece in roughly one step. So check those few lengths instead of every piece.

Hints

0 of 4 shown

Walkthrough and solution

Unlocks when you pass every test. Stuck for a while? Looking is fine too, as long as you then close it and write the code yourself.

Ctrl+Enter runs

Run your code to see results here. Run checks the examples. Submit checks every test, including hidden edge cases.

Write code