63 lines
1.5 KiB
Python
Executable File
63 lines
1.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from functools import reduce
|
|
from itertools import takewhile
|
|
import re, sys
|
|
import math
|
|
import numpy as np
|
|
|
|
def tpl(l):
|
|
me, rest = l[:-1].split(' (contains ')
|
|
return me.split(' '), rest.split(', ')
|
|
|
|
def uni(l):
|
|
return reduce(lambda a,b: a.union(b), l)
|
|
|
|
def inter(l):
|
|
return reduce(lambda a,b: a.intersection(b), l)
|
|
|
|
def dprint(*args):
|
|
sep = False
|
|
for arg in args:
|
|
if sep:
|
|
print('--------')
|
|
sep = True
|
|
for a, b in arg.items():
|
|
print('%10s: %s' % (a, ','.join(b)))
|
|
print()
|
|
|
|
fn = sys.argv[1] if len(sys.argv) > 1 else 'input%s' % 21
|
|
|
|
with open(fn) as f:
|
|
|
|
lines = [l.strip() for l in f.readlines()]
|
|
t = [tpl(l) for l in lines]
|
|
|
|
rec_per_al = {}
|
|
for rec, als in t:
|
|
for al in als:
|
|
if not al in rec_per_al:
|
|
rec_per_al[al] = []
|
|
rec_per_al[al] += [set(rec),]
|
|
|
|
ing_per_al = {a: inter(b) for a, b in rec_per_al.items()}
|
|
dprint(ing_per_al)
|
|
|
|
unsafe = uni(ing_per_al.values())
|
|
print(unsafe)
|
|
|
|
alling = uni([set(ing) for ing, al in t])
|
|
safe = alling - unsafe
|
|
|
|
tot = 0
|
|
for ing, _ in t:
|
|
tot += len([i for i in ing if i in safe])
|
|
print(tot)
|
|
|
|
bad, good = ing_per_al.copy(), {}
|
|
while bad:
|
|
for al, ing in filter(lambda x: len(x[1]) == 1, bad.items()):
|
|
good[al] = ing#.pop()
|
|
bad = {a: b - ing for a, b in bad.items() if a != al}
|
|
#dprint(good, bad)
|
|
print(','.join(good[i].pop() for i in sorted(good)))
|