Coding Interview Workshop · Lesson 24

Deliver a checked interview capstone

Deliver a small complete interview solution with a written grammar, aggregation rule, deterministic ranking and bounded output page.

Clarify the observable contract

Deliver a small complete interview solution with a written grammar, aggregation rule, deterministic ranking and bounded output page. Records contain one nonempty key, one colon and a nonnegative invariant integer quantity. Repeated ordinal keys add into checked long totals. Ranking is total descending then key ordinal ascending. This capstone uses an offset into a fixed snapshot, deliberately distinct from the earlier mutable-source keyset lesson.

Treat this as a deliverable with acceptance criteria rather than a puzzle whose only goal is one printout. The grammar, aggregation comparer, ordering and paging snapshot should all be written before coding. Keeping these contracts aligned is more important than compressing the pipeline into the fewest possible LINQ calls.

Walk through the verified program

b receives two and three for five, a receives one and c retains zero. Ranking produces b=5,a=1,c=0. Skipping one and taking two yields a,c, and the original four input strings remain available. Parsing rejects malformed delimiters or nonconforming numeric text instead of silently dropping a bad record.

The first colon is located once and a second colon is rejected. TryParse uses NumberStyles.None with invariant culture, so signs and surrounding whitespace are not silently admitted as quantities. The rank snapshot is created before paging, which makes the displayed offset refer to one known ordered result rather than a changing source.

using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

string[] input={"b:2","a:1","b:3","c:0"};
var totals=new Dictionary<string,long>(StringComparer.Ordinal);
foreach(string line in input) { int split=line.IndexOf(':'); if(split<=0 || line.IndexOf(':',split+1)>=0 || !int.TryParse(line.AsSpan(split+1),NumberStyles.None,CultureInfo.InvariantCulture,out int value)) throw new FormatException("record"); string key=line[..split]; totals[key]=checked(totals.GetValueOrDefault(key)+value); }
var ranked=totals.OrderByDescending(x=>x.Value).ThenBy(x=>x.Key,StringComparer.Ordinal).ToArray();
Console.WriteLine("ranked:"+string.Join(",",ranked.Select(x=>x.Key+"="+x.Value)));
var page=ranked.Skip(1).Take(2); Console.WriteLine("page:"+string.Join(",",page.Select(x=>x.Key)));
Console.WriteLine("input retained:"+input.Length);

Account for time, storage and allocations

For n input code units and u distinct keys, parsing and hashing examine text, aggregation uses expected dictionary work and ranking adds O(u log u) comparisons with O(u) retained totals and ranked storage. A two-item page bounds only output, not all work or memory.

Count text scanning, key hashing, retained totals and ranking separately. Skip one does not make the whole pipeline constant-time or constant-space because all records were parsed and all keys ranked first. The page is deliberately tiny, while the result snapshot remains proportional to the number of distinct keys.

Review assumptions and likely defects

Combining correct helpers can still produce a wrong system when their contracts disagree. The numeric grammar disallows signs and whitespace, whereas keys are preserved exactly. The fixed snapshot makes offset paging stable for this run; it does not make offsets safe across independent requests over changing data.

The helper currently stops at the first malformed record and publishes no completed result to a caller. If a product needs all parse errors at once, that is a different output contract with its own storage and error-position rules. Likewise, accepting signed adjustments would require a different numeric grammar and aggregation validation policy.

Practice one: discriminate edge cases

Add malformed quantities, duplicate delimiters, tied totals and zero-valued rows. Hint: test failures separately from the successful fixture so one bad row does not obscure ordering checks. Verify that input remains unchanged.

Use a tied total for two different keys and verify ordinal key order rather than first-seen order. Hint: the capstone intentionally selects a different tie contract from the top-K lesson. A regression test should make that choice visible so a reused helper cannot silently import the wrong ranking semantics.

Practice two: defend an extension

Present a time-boxed review explaining acceptance criteria, cost and one production extension. Choose whether to stream parsing, persist totals or sign continuation tokens, and state what additional tests and ownership rules that one extension would require.

A useful production extension is a bounded input parser that records record indices and returns structured validation failures before publishing totals. Keep the same ordinal aggregation and snapshot ranking unless the requirement explicitly changes. Add input-length and distinct-key budgets, then test that exceeding either leaves no partially returned successful result.

Evaluate correctness and interview reasoning

Present the capstone as a reviewable sequence of contracts and evidence: accepted grammar, duplicate handling, checked sums, deterministic order, page contents and retained input. The tested output can be derived entirely from four records, making it a reliable trace exercise. A senior explanation chooses one extension and follows its ownership, cost and failure consequences instead of claiming the console is a service. The separate question bank asks explanation, tracing and design questions about these same verified semantics, supporting self-review without turning an interview score into proof of production readiness.

A working example

using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

string[] input={"b:2","a:1","b:3","c:0"};
var totals=new Dictionary<string,long>(StringComparer.Ordinal);
foreach(string line in input) { int split=line.IndexOf(':'); if(split<=0 || line.IndexOf(':',split+1)>=0 || !int.TryParse(line.AsSpan(split+1),NumberStyles.None,CultureInfo.InvariantCulture,out int value)) throw new FormatException("record"); string key=line[..split]; totals[key]=checked(totals.GetValueOrDefault(key)+value); }
var ranked=totals.OrderByDescending(x=>x.Value).ThenBy(x=>x.Key,StringComparer.Ordinal).ToArray();
Console.WriteLine("ranked:"+string.Join(",",ranked.Select(x=>x.Key+"="+x.Value)));
var page=ranked.Skip(1).Take(2); Console.WriteLine("page:"+string.Join(",",page.Select(x=>x.Key)));
Console.WriteLine("input retained:"+input.Length);

Expected output

ranked:b=5,a=1,c=0
page:a,c
input retained:4
Try this
Add malformed quantities, duplicate delimiters, tied totals and zero-valued rows. Hint: test failures separately from the successful fixture so one bad row does not obscure ordering checks. Verify that input remains unchanged.

Further reading

Interview questions for this lesson