# 定义每个分组的规则
patterns = {
# 相邻的 4 个 X 组成一组,最高优先级
(0, 1, 4, 5): ['(~A)', '(A)'],
(1, 2, 5, 6): ['(B)', '(~B)'],
(3, 4, 7, 8): ['(C)', '(~C)'],
(4, 5, 8, 9): ['(D)', '(~D)'],
# 在两端列上的 4 个 X 组成一组,次高优先级
(0, 1, 2, 3, 12, 13, 14, 15): ['(~C)'],
# 相邻的 2 个 X 组成一组,按顺序加入项中,第三优先级
(0, 1): ['(~A&B)', '(A&~B)'],
(1, 2): ['(A&B)', '(~A&~B)'],
(4, 5): ['(~B&C)', '(B&~C)'],
(5, 6): ['(B&C)', '(~B&~C)'],
(8, 9): ['(~C&D)', '(C&~D)'],
(9, 10): ['(C&D)', '(~C&~D)'],
(12, 13): ['(~A&D)', '(A&~D)'],
(13, 14): ['(A&D)', '(~A&~D)'],
# 同行最左列和最右列的 2 个 X 组成一组,次优先级
(0, 4): ['(B&~C)'],
(1, 5): ['(~A&~C)'],
(3, 7): ['(A&C)'],
(4, 8): ['(A&~B)'],
# 最后一种情况,单独一个 X,最低优先级
(0,): ['(~A&~B&C)', '(A&B&~C)','(~A&~C&D)', '(A&C&~D)'], # 最左边的一列
(4,): ['(B&~C&D)', '(~B&C&~D)'], # 中间的两列
(8,): ['(~C&D&A)', '(C&~D&~A)'] # 最右边的一列
}
def get_bool_expression(pattern, x_values):
"""根据分组规则和变量值生成该分组对应的布尔表达式"""
expressions = patterns[pattern] # 获取该分组规则下的全部表达式
result = []
for exp in expressions:
for i in range(len(x_values)):
if exp.find(chr(65 + i)) != -1:
# 将表达式中的字母替换为变量的值
if x_values[i] == '0':
exp = exp.replace(chr(65 + i), '~' + chr(97 + i))
else:
exp = exp.replace(chr(65 + i), chr(97 + i))
result.append(exp)
return result
def veitch_to_bool(inputs):
"""将 Veitch 图转换为布尔表达式"""
# 将十六进制字符串转换为二进制字符串
binary_values = [bin(int(x, 16))[2:].zfill(4) for x in inputs]
patterns_list = list(patterns.keys())[::-1] # 将分组规则按优先级的高低排序并倒序
results = []
for pattern in patterns_list:
for i in range(0, 16, 4):
if all(binary_values[j][i+j%4] == '1' for j in pattern): # 判断该分组是否可用
results += get_bool_expression(pattern, [x[i+j%4] for j, x in enumerate(binary_values)])
break
# 合并生成的项及删除重复项
return ' + '.join(list(set(results)))
# 测试
inputs = ["33", "3C", "94", "77", "95"]
print(veitch_to_bool(inputs))