Problem overview
The method sellItem receives inventory, a dictionary from item names to how many of each a shop has, and the item a customer just bought. It sells one: the count of item drops by 1, and when it reaches 0 the item is removed from the dictionary. It returns the updated dictionary. The order of the entries doesn't matter.
With apples at 5 and pears at 2, selling an apple gives apples at 4. With cups at 1 and plates at 3, selling a cup removes "cups" and leaves only plates. Selling the only pen leaves an empty dictionary. The constraints promise that item is always a key and every count is at least 1.
Approach
Work out the count after the sale. If it is 0, delete the key. Otherwise store the smaller count. Because item is always present, a plain lookup is safe, so no default is needed.
Step by step
- Copy the parameter into a variable:
var result = inventory. Parameters are constants, and assigning a dictionary copies it. - Read the count with
result[item]!and subtract 1. Store it inremaining. The lookup gives anInt?, and the!unwraps it, which is safe because the key is always there. - If
remaining == 0, callresult.removeValue(forKey: item). The key and its value both go. - Otherwise, in an
elsebranch, setresult[item] = remaining. - Return
result.
The solution in Swift
class Solution {
func sellItem(_ inventory: [String: Int], _ item: String) -> [String: Int] {
var result = inventory
let remaining = result[item]! - 1
if remaining == 0 {
result.removeValue(forKey: item)
} else {
result[item] = remaining
}
return result
}
}
Printing each result as sorted key: value pairs gives:
apples: 4, pears: 2
plates: 3
The empty third line is the third example: after the pen is sold, the dictionary has no entries, so nothing is printed for it.
Language details
- The
!would crash on a missing key. Here the constraints rule that out. If a key could be missing, useif letordefault:instead. removeValue(forKey:)returns the old value, which this code ignores. Swift allows that for this method.- Setting
result[item] = 0would keep a key with a zero count, which is not what the task wants. The check for 0 is what removes it.
Edge cases and common mistakes
- Leaving a zero behind. If the count reaches 0, the key must go. Example 2 expects
["plates": 3], without"cups": 0. - Changing the wrong count. Only the entry for
itemchanges. Every other entry stays as it was. - Forgetting the else. Without it, the code would delete the key and then write it back.
- Skipping the copy. Writing to
inventorydirectly doesn't compile.
Cost
Each step is a single dictionary lookup, write or removal, so the method does a fixed amount of work no matter how many different items the shop holds, apart from the copy of the dictionary at the start.
Testing
Two more inputs are worth running:
["jam": 2, "tea": 4], selling"jam", givesjam: 1, tea: 4. With one left, the key stays.["pen": 3], selling"pen", givespen: 2. A one-entry dictionary with a count above 1 does not become empty.
The test that matters most is the one where the count reaches 0, because that is the only path that removes a key.
