C# & .NET Framework Collections & LINQ Magic
💡
Exercise 42

Dictionary, Sets & Queues 20 XP Medium

Ctrl+Enter Run Ctrl+S Save

The City Services Directory 🗂️

A city doesn't just have residents — it has services indexed by name, unique permits that can't be duplicated, and task queues for processing requests. C# gives us specialized collections for each of these patterns: Dictionary<TKey, TValue> for key-value lookups, HashSet<T> for unique elements, Queue<T> for first-in-first-out processing, and Stack<T> for last-in-first-out undo operations.

Dictionary<TKey, TValue> — Instant Lookups

A Dictionary maps unique keys to values using a hash table internally. Lookups, insertions, and deletions are all O(1) average case. Think of it as the city's phone book — you look up a department name and instantly get its info.

Dictionary<string, int> cityServices = new Dictionary<string, int>(); // Adding entries cityServices.Add("Fire Station", 5); // 5 trucks cityServices["Police"] = 10; // 10 officers (indexer syntax) cityServices["Hospital"] = 20; // 20 beds // Reading values Console.WriteLine($"Fire Station: {cityServices["Fire Station"]} trucks"); // Safe lookup with TryGetValue (avoids KeyNotFoundException) if (cityServices.TryGetValue("Library", out int books)) Console.WriteLine($"Library: {books} books"); else Console.WriteLine("Library not found");
  • Add(key, value) — Adds a new key-value pair; throws if key exists
  • dict[key] = value — Sets value; adds if not present, overwrites if present
  • TryGetValue(key, out value) — Safe lookup returning bool; avoids exceptions
  • ContainsKey(key) — Returns true if the key exists
  • Remove(key) — Removes the entry by key
  • Count — Number of key-value pairs
  • Keys / Values — Collections of all keys or all values

HashSet<T> — Unique Elements Only

A HashSet<T> stores unique elements with O(1) lookups. Duplicates are silently ignored. It also supports set operations like UnionWith, IntersectWith, and ExceptWith.

HashSet<string> departments = new HashSet<string>(); departments.Add("Fire"); departments.Add("Police"); departments.Add("Hospital"); departments.Add("Fire"); // Ignored — already exists! Console.WriteLine($"Departments: {departments.Count}"); // 3 Console.WriteLine($"Has Hospital: {departments.Contains("Hospital")}"); // True

Queue<T> — First In, First Out (FIFO)

A Queue<T> processes items in the order they were added — just like a real queue at city hall. Use Enqueue to add and Dequeue to remove from the front.

Queue<string> permitQueue = new Queue<string>(); permitQueue.Enqueue("Permit A"); permitQueue.Enqueue("Permit B"); permitQueue.Enqueue("Permit C"); string next = permitQueue.Dequeue(); // "Permit A" Console.WriteLine($"Processing: {next}"); Console.WriteLine($"Remaining: {permitQueue.Count}"); // 2 // Peek without removing string upcoming = permitQueue.Peek(); // "Permit B"

Stack<T> — Last In, First Out (LIFO)

A Stack<T> is perfect for undo operations. The last action pushed is the first one popped. Think of it as the Architect's undo history.

Stack<string> undoStack = new Stack<string>(); undoStack.Push("Build"); undoStack.Push("Paint"); undoStack.Push("Furnish"); string lastAction = undoStack.Pop(); // "Furnish" Console.WriteLine($"Undo: {lastAction}"); // Peek at the next undo without removing string nextUndo = undoStack.Peek(); // "Paint" Console.WriteLine($"Next undo: {nextUndo}");

When to Use What?

  • Dictionary — When you need fast key-based lookups (config settings, caches, lookups by ID)
  • HashSet — When you need guaranteed uniqueness and fast membership checks
  • Queue — When you process items in arrival order (message queues, BFS, job processing)
  • Stack — When you need LIFO behavior (undo systems, expression parsing, DFS)

Time to wire up all four collection types for the city's service management system, Architect!

📋 Instructions
**Build the City Services Directory & Task Management System!** 1. Create a `Dictionary` called `services` 2. Add these entries: key `"Fire Station"` → value `"5 trucks"`, key `"Police"` → value `"10 officers"`, key `"Hospital"` → value `"20 beds"` 3. Print `"Fire Station: "` followed by the value for key `"Fire Station"` 4. Print `"Police: "` followed by the value for key `"Police"` 5. Create a `HashSet` called `departments`, add `"Fire"`, `"Police"`, `"Hospital"`, and `"Fire"` again 6. Print `"Has Hospital: "` followed by whether the set contains `"Hospital"` 7. Create a `Queue` called `permits`, enqueue `"Permit A"`, `"Permit B"` 8. Dequeue one item and print `"Queue: "` followed by the dequeued item, then `" processed"` 9. Create a `Stack` called `actions`, push `"Build"` then `"Paint"` 10. Pop the top and print `"Stack: Undo last action: "` followed by the popped value
For Dictionary, use the indexer `services["key"]` to read values. HashSet.Contains() returns a bool. Queue uses Enqueue/Dequeue, Stack uses Push/Pop. Remember that `$"text {variable}"` is string interpolation.
main.py
Hi! I'm Rex 👋
Output
Ready. Press ▶ Run or Ctrl+Enter.