cswork / libraryOpen practice workspace

Coding questions · Hopper

How would you sort filenames with numeric segments?

This question evaluates a candidate's ability to design custom string comparators, parse maximal digit runs and compare numeric values, and handle edge cases such as leading zeros and digit-versus-non-digit ordering.

You are given a list of filename strings (e.g., "file10.txt", "file2.txt", "10file.txt"). Implement a custom sort for these strings using a comparator with the following rules:

  1. Digit-first at the first differing position: When comparing two strings from left to right, if at the first position where they differ one string has a digit (0-9) and the other has a non-digit, the digit one should come first.
  2. Numeric comparison for digit runs: Treat any maximal consecutive digit substring as a single number and compare by numeric value (so "file10.txt" comes after "file2.txt").
  3. Normal character order for non-digit runs: Compare non-digit parts in standard character/lexicographic order.

Return the filenames sorted according to these rules.

Follow-ups:

  • Leading zeros: How should "file01.txt" and "file1.txt" be ordered if their numeric values are equal? Implement your chosen tie-break rule.
  • Performance: If there are very many filenames, repeatedly parsing digit runs inside the comparator can be slow. How would you optimize the sorting implementation?

Sort Filenames with Numeric Segments

Sort filenames using digit-first comparison, numeric comparison for digit runs, and lexicographic comparison for non-digit runs. Equal numeric values tie by shorter digit run then raw digits.

Examples

Example 1

Input: (['file10.txt','file2.txt','10file.txt'],)
Output: ['10file.txt', 'file2.txt', 'file10.txt']

Explanation: Numeric runs and digit-first.

Example 2

Input: (['file01.txt','file1.txt','file001.txt'],)
Output: ['file1.txt', 'file01.txt', 'file001.txt']

Explanation: Leading-zero tie-break.

Hints

  1. Model object-style prompts as operation streams when needed.
  2. Handle empty and boundary cases before the main logic.