Problem overview
guestsMissing gets two slices of names, invited and arrived, and returns how many invited guests have not arrived. A guest can check in more than once and still counts as one. Someone who wasn't invited can check in too, and that changes nothing.
With invited = ["Ava", "Leo", "Mia", "Zoe"] and arrived = ["Leo", "Zoe"] the answer is 2: Ava and Mia are missing. With ["Ava", "Leo"] and ["Leo", "Max", "Leo"] the answer is 1: Leo checked in twice but is one guest, and Max wasn't invited. With nobody arrived, every invited guest is missing.
Approach
Start with everybody missing and cross names off as people arrive. A map used as a set suits that: it holds each name once, and delete removes a name without complaint even when it is not there. That one property covers both tricky cases. An uninvited guest isn't a key, so delete does nothing. A guest who checks in twice is removed the first time, and the second delete does nothing.
What remains in the set at the end is exactly the invited guests who never checked in, so len of the set is the answer.
Step by step
- Create the set
missing := map[string]bool{}. - Loop over
invitedand setmissing[name] = true. The names ininvitedare all different, so each becomes its own key. - Loop over
arrivedand calldelete(missing, name). - Return
len(missing).
The solution in Go
func guestsMissing(invited []string, arrived []string) int {
missing := map[string]bool{}
for _, name := range invited {
missing[name] = true
}
for _, name := range arrived {
delete(missing, name)
}
return len(missing)
}
Each loop writes _, name because only the value of each slice element is needed, not its index. Go would refuse to compile an index variable that is never used.
Tracing the second example makes the two tricky cases visible. The set starts with two names, so len(missing) is 2. After the first arrival, Leo, delete removes him and the length is 1. Max was never invited, so delete finds nothing and the length stays 1. The second Leo is already gone, so the length stays 1 again. The function returns 1, and only Ava is missing.
The order of the two loops matters: the invited guests must go in first, otherwise there would be nothing to delete from. Also note that the answer comes from the set itself. It is not computed from the slice lengths, since the slices can include repeats and uninvited people.
Testing
Running the function on the examples gives:
invited = [Ava Leo Mia Zoe], arrived = [Leo Zoe] -> 2
invited = [Ava Leo], arrived = [Leo Max Leo] -> 1
invited = [Sam Kim], arrived = [] -> 2
Another way to think about the same task is to build a set of the arrivals and count the invited names that are not in it. That also works, but it needs a test inside the counting loop. Removing names from a set of the invited guests needs no test at all, and the answer is just the size of what is left.
Common mistakes
- Counting the arrivals.
len(arrived)counts repeats and uninvited guests. Only the invited names matter. - Subtracting lengths.
len(invited) - len(arrived)goes wrong as soon as someone checks in twice or wasn't invited. - Checking whether the name is present before deleting. It isn't needed;
deleteon a missing key is safe.
