Brute force with some bounds for this problem would be very fast (70 milliseconds). In the following code, I used the following bounds:
- Instead of brute force 9! permutations, we can first try all the permutations for the first 3 digits (in the first two numbers)
- The next 2 digits (the 3rd number), thus can be calculated since they are the first product. We can eliminate cases where the digits in the first result duplicate some digits in the first 3 digits, or the result has more than 2 digits
- We then try all the permutations of 2 among the remaining 4 digits to form the 4th number, get the second result (the some of the 3rd and 4th number), and check if any digits are used more than once.
So in the worst case, we only need to try 9*8*7*4*3 = 6048 (9*8*7 from the 3-permutation in step 1, and 4*3 from the 2-permutation in step 3), not even mentioning the fact that many cases are eliminated in the 2nd step.
import itertools
def solve():
digits = list(range(1,10))
for a, b, c in itertools.permutations(digits, 3):
res = (a*10+b)*c # third number
if res > 100: # third number uses more than 2 digits
continue
d, e = res//10, res%10
used = set([a,b,c,d,e])
if len(used) < 5: # duplicate digits
continue
left = set(digits).difference(used)
for f, g in itertools.permutations(left, 2):
res = d*10 + e + f*10 + g # final number
h, k = res//10, res%10
if set([f,g,h,k]) == left:
print("{}{}*{}={}{}".format(a,b,c,d,e))
print("{}{}+{}{}={}{}".format(d,e,f,g,h,k))
import time
start = time.time()
solve()
print("Solve in {:.3}s".format(time.time()-start))
The solution is
17*4=68
68+25=93
Solve in 0.073s
9otherwise the third row need 3 digits. Another problem (each letter one digit, no repititions),with other conditions isSEND + MORE = MONEY