2021-08-26 18:32:55 +08:00
|
|
|
with open('mctrl1.txt') as f:
|
2021-07-05 15:25:15 +08:00
|
|
|
lines = f.readlines()
|
|
|
|
title = lines[0].split()
|
|
|
|
items = [x.split() for x in lines[1:]]
|
|
|
|
|
2021-07-07 16:55:10 +08:00
|
|
|
preq = title[0].count('/')
|
2021-07-07 13:32:23 +08:00
|
|
|
bits = title[0].count('-')
|
|
|
|
|
2021-07-05 15:25:15 +08:00
|
|
|
def gini(d):
|
|
|
|
s = set(v for k, v in d)
|
|
|
|
g = 1
|
|
|
|
for i in s:
|
|
|
|
g -= (sum(1 for k, v in d if v == i) / len(d)) ** 2
|
|
|
|
return g
|
|
|
|
|
2021-08-01 15:46:53 +08:00
|
|
|
def readable_and(s, t):
|
2021-07-05 15:25:15 +08:00
|
|
|
if(len(t) == 0):
|
|
|
|
return s
|
|
|
|
return s + ' & ' + t
|
|
|
|
|
2021-08-01 15:46:53 +08:00
|
|
|
def readable_merge(d0, d1, i):
|
2021-07-05 15:25:15 +08:00
|
|
|
d = d0 | d1
|
|
|
|
for k in d:
|
|
|
|
if(k not in d0):
|
2021-08-01 15:46:53 +08:00
|
|
|
d[k] = readable_and('[{}]'.format(i), d1[k])
|
2021-07-05 15:25:15 +08:00
|
|
|
elif(k not in d1):
|
2021-08-01 15:46:53 +08:00
|
|
|
d[k] = readable_and('~[{}]'.format(i), d0[k])
|
2021-07-05 15:25:15 +08:00
|
|
|
else:
|
2021-08-01 15:46:53 +08:00
|
|
|
d[k] = '({} | {})'.format(readable_and('~[{}]'.format(i), d0[k]), readable_and('[{}]'.format(i), d1[k]))
|
2021-07-05 15:25:15 +08:00
|
|
|
return d
|
|
|
|
|
2021-08-01 15:46:53 +08:00
|
|
|
def solve(d, mask = 0):
|
|
|
|
if(len(d) == 0):
|
|
|
|
return {}
|
2021-07-05 15:25:15 +08:00
|
|
|
s = set(v for k, v in d)
|
|
|
|
if(len(s) == 1):
|
|
|
|
return {s.pop(): ''}
|
|
|
|
min_gini = -1
|
|
|
|
min_idx = -1
|
2021-07-07 13:32:23 +08:00
|
|
|
for i in range(0, bits):
|
2021-08-01 15:46:53 +08:00
|
|
|
if(mask & 1 << i):
|
|
|
|
continue
|
2021-07-05 15:25:15 +08:00
|
|
|
s0 = [(k, v) for k, v in d if k[i] == '0']
|
|
|
|
s1 = [(k, v) for k, v in d if k[i] == '1']
|
2021-08-01 15:46:53 +08:00
|
|
|
if(len(s0) + len(s1) != len(d) or len(s0) == 0 or len(s1) == 0):
|
2021-07-05 15:25:15 +08:00
|
|
|
continue
|
|
|
|
g = gini(s0) * len(s0) / len(d) + gini(s1) * len(s1) / len(d)
|
|
|
|
if(min_idx == -1 or g < min_gini):
|
|
|
|
min_gini = g
|
|
|
|
min_idx = i
|
|
|
|
if(min_idx == -1):
|
|
|
|
raise "fuck"
|
|
|
|
s0 = [(k, v) for k, v in d if k[min_idx] == '0']
|
|
|
|
s1 = [(k, v) for k, v in d if k[min_idx] == '1']
|
2021-08-01 15:46:53 +08:00
|
|
|
return readable_merge(solve(s0, mask | 1 << min_idx), solve(s1, mask | 1 << min_idx), bits - 1 - min_idx)
|
2021-07-05 15:25:15 +08:00
|
|
|
|
|
|
|
for i in range(1, len(title)):
|
|
|
|
print(title[i])
|
2021-07-07 16:55:10 +08:00
|
|
|
ans = solve([(item[0][preq:], item[i]) for item in items if item[i] != '?'])
|
2021-08-01 15:46:53 +08:00
|
|
|
kind = set(item[i] for item in items if item[i] != '?')
|
|
|
|
if(len(kind) == 4):
|
|
|
|
print(4)
|
2021-07-05 15:25:15 +08:00
|
|
|
print(ans)
|