Coding interviews
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
string text="A\U0001F600e\u0301";
Console.WriteLine("UTF16:"+text.Length); Console.WriteLine("scalars:"+text.EnumerateRunes().Count());
int[] starts=StringInfo.ParseCombiningCharacters(text); Console.WriteLine("text elements:"+starts.Length);
Console.WriteLine("first two:"+Prefix(text,2));
static string Prefix(string text,int count) { if(count<0) throw new ArgumentOutOfRangeException(nameof(count)); int[] starts=StringInfo.ParseCombiningCharacters(text); return count>=starts.Length?text:text[..starts[count]]; }
Reveal answer and reasoning
The output lines, in order, are “UTF16:5”; “scalars:4”; “text elements:3”; “first two:A😀”. The sample contains A, one supplementary emoji, e and a combining acute accent. Those occupy five UTF-16 code units, four scalars and three text elements. Taking the first two text elements returns A followed by the intact emoji. The prefix function uses element start indices instead of slicing at the requested count of code units.
The element-start array identifies A at zero, the emoji at one and the combining sequence at three. Selecting boundary index two therefore slices before the e, retaining the emoji's complete surrogate pair. The four scalar count includes the combining accent separately, which explains why scalar-aware truncation alone is not the same requirement.
Parsing all element boundaries takes O(n) work and O(g) index storage for g text elements. The substring result can allocate O(n) code units. This implementation prioritizes a clear boundary contract rather than a minimal-allocation prefix scan. Unicode segmentation behavior follows the runtime implementation. Rune is not the same as a user-perceived grapheme, and string.Length is not a display width. Equal-looking strings can still differ ordinally without normalization.
Input containing unpaired surrogates or requirements for locale-specific presentation need an explicit policy beyond this fixed valid-Unicode fixture.
What a strong answer covers
- Exact output: UTF16:5 | scalars:4 | text elements:3 | first two:A😀
- The sample contains A, one supplementary emoji, e and a combining acute accent.
- Rune is not the same as a user-perceived grapheme, and string.Length is not a display width.
Common pitfall
Rune is not the same as a user-perceived grapheme, and string.Length is not a display width. Equal-looking strings can still differ ordinally without normalization. Input containing unpaired surrogates or requirements for locale-specific presentation need an explicit policy beyond this fixed valid-Unicode fixture.
Follow-up questions
- Test count zero, a count beyond the element count and precomposed versus decomposed accented text. Hint: compare both preserved code units and element counts rather than assuming normalization occurred.
- How can normalization invalidate offsets that were measured in the original spelling?
Self-review
Choose what to revisit. These marks are your own assessment and are separate from lesson completion.