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.