我目前有以下两项,都必须为true:
A B C D + A E F = E F G H和
I C J * E = A B C D
每个字母代表一个从0到9的唯一数字,并且两个等式都必须成立。 我需要编写一个输出正确答案的Python解决方案,这是我的代码:
import numpy as np
def solve():
for a in range(0,10):
for b in range(0,10):
for c in range(0,10):
for d in range(0,10):
for e in range(0,10):
for f in range(0,10):
for g in range(0,10):
for h in range(0,10):
for i in range(0,10):
for j in range(0,10):
if len(set([a, b, c, d, e, f, g, h, i, j])) == 10:
icj = 100*i + 10*c + j
e = e
abcd = 1000*a + 100*b + 10*c + d
aef = 100*a + 10*e + f
efgh = 1000*e + 100*f + 10*g + h
if icj * e == abcd and abcd + aef == efgh:
print(icj, e, abcd, aef, efgh)
print(solve())
但是,当我运行此命令时,不仅需要花一些时间才能运行,而且还会输出“无”。关于我要去哪儿有什么想法吗?
答案 0 :(得分:4)
您应该尝试使用for x in range(0, 10)
而不是for x in range(0,9)
,因为您是从0循环到8。
如果您想以更有效的方式循环,则可以使用permutations:
from itertools import permutations
for a, b, c, d, e, f, g, h, i, j in permutations(range(0, 10), 10):
print(a, b, c, d, e, f, g, h, i, j)
结果:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 9 8
...
9 8 7 6 5 4 3 2 0 1
9 8 7 6 5 4 3 2 1 0
这是最终代码:
import numpy as np
from itertools import permutations
def solve():
for a, b, c, d, e, f, g, h, i, j in permutations(range(0, 10), 10):
icj = 100*i + 10*c + j
e = e
abcd = 1000*a + 100*b + 10*c + d
aef = 100*a + 10*e + f
efgh = 1000*e + 100*f + 10*g + h
if icj * e == abcd and abcd + aef == efgh:
print(icj, e, abcd, aef, efgh)
print(a, b, c, d, e, f, g, h, i, j)
solve()
输出:
934 7 6538 672 7210
6 5 3 8 7 2 1 0 9 4
答案 1 :(得分:1)
除错别字外,如果仅在内部循环中测试所有10位数字是否都不同,则此内部循环将执行10 10 = 10,000,000,000次。如果您每次通过测试,则“仅”需要10个! = 3,628,800传递到此内部循环。
您仍然可以更好地更改变量的顺序,因此可以测试方程式abc * d == hibj
,而无需其他三个变量,只有等式成立时,它才能更深入。对于这7位数字,您在该循环中输入604,800次,而只需要更深入45次即可到达最内部的循环,仅270次。
def solve():
for a in range(0, 10):
for b in range(0, 10):
if a != b:
for c in range(0, 10):
if not c in [a, b]:
for d in range(0, 10):
if not d in [a, b, c]:
for h in range(0, 10):
if not h in [a, b, c, d]:
for i in range(0, 10):
if not i in [a, b, c, d, h]:
for j in range(0, 10):
if not j in [a, b, c, d, h, i]:
abc = 100 * a + 10 * b + c
hibj = 1000 * h + 100 * i + 10 * b + j
if abc * d == hibj:
print(abc, '*', d, '=', hibj)
for e in range(0, 10):
if not e in [a, b, c, d, h, i, j]:
for f in range(0, 10):
if not f in [a, b, c, d, h, i, j, e]:
for g in range(0, 10):
if not g in [a, b, c, d, h, i, j, e, f]:
hde = 100 * h + 10 * d + e
defg = 1000 * d + 100 * e + 10 * f + g
if hibj + hde == defg:
print(abc, d, hibj, hde, defg)
solve()
print('done')
尽管它现在可以运行得足够快,但是可以考虑更具体的优化:
a,b,c
和h,i,j
,然后计算hibj
是否为abc
的倍数。仅在情况允许的情况下,此定义d
应该在0
和9
之间,并且与其他地方不同。a,b,c,d
,然后首先尝试所有倍数是否适合b
,然后尝试相应的h,i,j
是否彼此不同且与{{1 }}。a,b,c,d
应该小于h
,否则a
将大于d
。这使得9
至少a
。另一种方法是使用SMT/SAT之类的Z3求解器。使用这样的求解器,可以制定所有条件,并通过各种试探法寻找解决方案。示例代码:here和here。
这是代码的样子:
1
这将打印出from z3 import Int, And, Or, Distinct, Solver, sat
D = [Int(f'{c}') for c in "abcdefghij"]
a, b, c, d, e, f, g, h, i, j = D
vals_0_to_9 = [And(Di >= 0, Di <= 9) for Di in D]
all_different = [Distinct(D)]
abc = 100 * a + 10 * b + c
hibj = 1000 * h + 100 * i + 10 * b + j
hde = 100 * h + 10 * d + e
defg = 1000 * d + 100 * e + 10 * f + g
equations = [abc * d == hibj, hibj + hde == defg]
s = Solver()
s.add(vals_0_to_9 + all_different + equations)
while s.check() == sat:
m = s.model()
print(", ".join([f'{Di}={m[Di]}' for Di in D]))
s.add(Or([Di != m[Di] for Di in D]))
作为唯一解决方案。