欧拉计划 32

如果一个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))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值