Problem overview
The function sellItem gets inventory, a MutableMap<String, Int> 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 map. It returns the updated map. The item is always a key, every count is at least 1, and the order of entries doesn't matter.
With {"apples": 5, "pears": 2} and "apples", the apples drop to 4. With {"cups": 1, "plates": 3} and "cups", the last cup is sold, so "cups" disappears and only the plates remain. With {"pen": 1} and "pen", the map ends up empty.
Approach
There are two outcomes: the item stays with a smaller count, or it leaves. Work out the new count first, then decide. If it is 0, the key goes with remove. Otherwise the key is assigned the new count, which replaces the old one. Because the task guarantees the key exists, reading its count can't fail.
Step by step
- Compute what is left. Read the count with
inventory[item]!!and subtract 1, storing it in avalnamedremaining. The read has the typeInt?because a key could be missing in general, and!!turns it into a plainInt. That is safe here because the task guarantees the key. - Sold out? If
remaining == 0, callinventory.remove(item). The key and its value both go. - Otherwise update. In the
elsebranch, setinventory[item] = remaining. - Return
inventory. Only the entry foritemchanged, or it is gone.
The solution in Kotlin
class Solution {
fun sellItem(inventory: MutableMap<String, Int>, item: String): MutableMap<String, Int> {
val remaining = inventory[item]!! - 1
if (remaining == 0) {
inventory.remove(item)
} else {
inventory[item] = remaining
}
return inventory
}
}
Printing each result as sorted key: value lines (the tests' format) gives, for the three examples:
apples: 4
pears: 2
plates: 3
(no lines: the map is empty)
Note the precedence in inventory[item]!! - 1: the !! applies to the value that was read, then the subtraction runs on the plain Int.
Edge cases and common mistakes
- Subtracting without removing. Writing only
inventory[item] = inventory[item]!! - 1leavescups: 0in the map after the last cup is sold, instead of removing the key. - Removing at the wrong moment. Take the item out only when the new count is 0, not whenever the count is small. A shop with 2 cups left must keep the key, with 1 cup.
- Forgetting
!!. Without it,inventory[item] - 1doesn't compile: anInt?has no-, and the compiler says the call is prohibited on a nullable receiver. - Touching other entries. Only the sold item's entry changes: the plates stay at 3 in the second example.
- A single-item map. Removing the only key gives an empty map, which is the correct answer for the third example.
What happens to the map
For {"cups": 1, "plates": 3} and "cups", the read gives 1, so remaining is 0. Up to that point the map is untouched and still holds both items. The if branch then calls remove("cups"), which leaves {plates=3}, and the else branch is skipped. For "apples" in the first example the count is 5, so remaining is 4, the if is skipped, and the else branch stores 4 under "apples".
Testing
{"apples": 5, "pears": 2}, "apples" gives apples: 4 and pears: 2.{"cups": 1, "plates": 3}, "cups" gives only plates: 3.{"pen": 1}, "pen" gives an empty map.
