如果一个n位数使用了1到n中每个数字且只使用了一次,我们称其为pandigital。
例如,15234这个五位数,是1到5pandigital的。
7254是一个不寻常的数,因为:39 × 186 = 7254这个算式的乘数,被乘数和乘积组成了一个1到9的pandigital组合。
找出所有能够组合成1到9pandigital的乘法算式中乘积的和。
提示: 有的乘积数字能够被多个乘法算式得到,所以在计算时要记得只计算它们一次。
# i_a_val * i_b_val = i_c_val
# i_a_val < i_b_val < i_c_val
# a,b,c 分别为 i_a_val,i_b_val,i_c_val的位数
prod_set = set()
for a in range(1, 4):
for b in range(a, 7 - a):
c = 9 - a - b
# 注意位数的判断
if b > c:
break
if (10 ** a - 1) * (10 ** b - 1) < 10 ** (c - 1):
continue
if 10 ** (a - 1) * 10 ** (b - 1) > 10 ** c - 1:
continue
# 排列
for i_a in itertools.permutations(set(range(1, 10)), a):
if i_a[-1] == 1:
continue
i_a_val = sum([v * 10 ** (a - 1 - i) for i, v in enumerate(i_a)])
for i_b in itertools.permutations(set(range(1, 10)) - set(i_a), b):
if i_b[-1] == 1:
continue
i_b_val = sum([v * 10 ** (b - 1 - i) for i, v in enumerate(i_b)])
i_c_val = i_a_val * i_b_val
# 位数判断
if int(math.log10(i_c_val)) + 1 != c:
continue
# 利用set来判断1到9的pandigital组合
c_set = set(range(1, 10)) - set(i_a) - set(i_b)
while i_c_val:
if i_c_val % 10 in c_set:
c_set.remove(i_c_val % 10)
else:
break
i_c_val //= 10
if len(c_set) == 0:
prod_set.add(i_a_val * i_b_val)
print(sum(prod_set))