我想缩短这段代码:
if (a+b+c == 1000 and a**2 + b**2 == c**2) or (a+b+c == 1000 and a**2 + c**2 == b**2) or (a+b+c == 1000 and b**2 + c**2 == a**2)
到:
if a+b+c == 1000 and (a**2 + b**2 == c**2 or a**2 + c**2 == b**2 or b**2 + c**2 == a**2)
或者更简单一点:
(A and B) or (A and C) or (A and D) <=> A and (B or C or D)
这合理吗?当我运行代码时它似乎有效,但我不确定这是正确的方法。有没有更好的方法来缩短这个时间?
你是对的。
在数学符号中,以下等式成立:
(A ∧ B) ∨ (A ∧ C) ∨ (A ∧ D) = A ∧ (B ∨ C ∨ D)
这通常称为 CNF 或 DNF 形式的归一化。
是的! 正如乌列尔所提到的,这在数学上是合理的。此外,您已经注意到 python 支持该符号。 下面的真值表显示它也按预期进行了评估:
>>> for a, b, c in itertools.product([True, False], repeat=3):
... print('%5s | %5s | %5s || %5s') % (a, b, c, (a or b or c))
...
True | True | True || True
True | True | False || True
True | False | True || True
True | False | False || True
False | True | True || True
False | True | False || True
False | False | True || True
False | False | False || False
布尔逻辑说它是等价的。但更好的方法是"测试驱动开发":首先编写所有可能结果的测试。然后针对第一个实现运行它们,然后针对重构的实现运行它们。
更新,基于Cireo的回答:
import itertools
for a, b, c, d in itertools.product([True, False], repeat=4):
print('%5s | %5s | %5s | %5s || %5s || %5s') % (a, b, c, d, (a and b) or (a and c) or (a and d), a and (b or c or d))
True | True | True | True || True || True
True | True | True | False || True || True
True | True | False | True || True || True
True | True | False | False || True || True
True | False | True | True || True || True
True | False | True | False || True || True
True | False | False | True || True || True
True | False | False | False || False || False
False | True | True | True || False || False
False | True | True | False || False || False
False | True | False | True || False || False
False | True | False | False || False || False
False | False | True | True || False || False
False | False | True | False || False || False
False | False | False | True || False || False
False | False | False | False || False || False
在这里证明这两个语句对于所有变量的所有值都是等价的。