**Part 1:** Given a list of target values of the form:

```
children: 3
cats: 7
samoyeds: 2
```

And a list of ‘Aunt Sues’, each with known values:

```
Sue 1: children: 1, cars: 8, vizslas: 7
Sue 2: akitas: 10, perfumes: 10, children: 5
Sue 3: cars: 5, pomeranians: 4, vizslas: 1
```

Determine which Sue has no unset but matching values.

For example, Sue 1 is invalid because `children`

is 1 versus 3 and Sue 2 because `children`

is 5 versus 3. Given only the values above, Sue 3 would be valid since there are no contradictions.

I think understanding this problem took longer than solving it. Originally, I thought that missing values should be treated as `float('inf')`

, but they should just be ignored entirely:

```
targets = {}
sues = collections.defaultdict(dict)
loading_targets = True
for line in sys.stdin:
line = line.strip()
if not line:
loading_targets = False
elif loading_targets:
key, val = line.split(': ')
targets[key] = int(val)
else:
sue, things = line.strip().split(': ', 1)
for thing in things.split(', '):
key, val = thing.split(': ')
sues[sue][key] = int(val)
for sue in sues:
valid = True
for key in targets:
if key in sues[sue] and sues[sue][key] != targets[key]:
valid = False
break
if valid:
print(sue)
```

The longer half is correctly parsing and loading the data. For my case, I put both inputs in the same stream, separated by an empty line (similar to HTTP and other protocols actually).

After that, it was just a matter of checking each Sue for the first existent but non-matching value.

**Part 2:** Repeat the same algorithm, however assume that a Sue must have strictly more `cats`

and `trees`

than listed and strictly less `pomeranians`

and `goldfish`

.

For this, I introduced another `defaultdict`

which contains the `comparators`

to use for any given value:

```
comparators = collections.defaultdict(lambda : operator.eq)
comparators['cats'] = comparators['trees'] = operator.gt
comparators['pomeranians'] = comparators['goldfish'] = operator.lt
```

After that, we can change the `for sue in sues`

loop to take the comparator into account:

```
for sue in sues:
valid = True
for key in targets:
if key in sues[sue] and not comparators[key](sues[sue][key], targets[key]):
valid = False
break
if valid:
print(sue)
```

Neat.