首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python中的euler 43项目

Python中的euler 43项目
EN

Stack Overflow用户
提问于 2016-10-17 16:58:20
回答 1查看 468关注 0票数 1

我遇到了另一个困难的项目--欧拉问题链接到问题

我的第一反应是尝试一个简单的蛮力解决方案,这花费了太多的时间。

所以我想出了一个更好的解决方案,但我不知道如何对它进行编码。

我想:

  1. 生成所有必要的三胞胎。
  2. 把所有的组合组合在一起。
  3. 算一算。

我做了第一步,我的结果如下:

代码语言:javascript
运行
复制
Multiples of 17: [[0, 1, 7], [0, 3, 4], [0, 5, 1], [0, 6, 8], [0, 8, 5], [1,   0, 2], [1, 3, 6], [1, 5, 3], [1, 7, 0], [1, 8, 7], [2, 0, 4], [2, 3, 8], [2, 8, 9], [3, 0, 6], [3, 4, 0], [3, 5, 7], [3, 7, 4], [3, 9, 1], [4, 0, 8], [4, 2, 5], [4, 5, 9], [4, 7, 6], [4, 9, 3], [5, 1, 0], [5, 2, 7], [5, 6, 1], [5, 7, 8], [6, 1, 2], [6, 2, 9], [6, 8, 0], [6, 9, 7], [7, 1, 4], [7, 3, 1], [7, 4, 8], [7, 6, 5], [7, 8, 2], [8, 1, 6], [8, 5, 0], [8, 6, 7], [9, 0, 1], [9, 1, 8], [9, 3, 5], [9, 5, 2], [9, 8, 6]] etc...

现在对我来说棘手的部分来了。我试着用嵌套循环把它们组合在一起,但那真的很麻烦。如果您有任何建议,请告诉我:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-28 03:49:49

首先,暴力解决方案几乎不需要任何时间运行。

正如@MooingRawr建议的那样,如果使用itertools.permutations,只有~0.9x9!不以零开头的0123456789的排列。

代码语言:javascript
运行
复制
from itertools import permutations

primes = [17, 13, 11, 7, 5, 3, 2]

total = 0

# Generate permutations of 10 distict digits -- 10 factorial
for i in permutations('0123456789'):

  # Discard those that begin with zero -- one-tenth of 10!
  if i[0] == '0':
    continue 

  # Convert into a string and assume that it is valid
  n = ''.join(list(i))
  valid = True

  # Check if the last three digits are divisible by 17, ...
  #    ... then shift left and check if those digits are divisible by 13, etc.
  for j in xrange(0, len(primes)):
    x = n[len(primes) - j:len(primes) - j + 3]
    if int(x) % primes[j]:
      valid = False
      break

  # Print and add
  if valid:
    print 'Valid number: %s' % n
    total += int(n)

print 'Total: %d' % total

如果您运行此解决方案这里,它将在几秒钟内运行,这对于PE来说应该是可以的。

然而,您建议的方法确实更有效。注意,您已经硬编码了七个循环,我只是使用factors来生成它们,其中factor[i]是d_i d_i+1 d_i+2的一个因素。

您担心会生成所有的组合,但是使用递归是很简单的,每次迭代都检查最后两个数字并找到一个有效的下一个数字。

代码语言:javascript
运行
复制
factors = [1, 2, 3, 5, 7, 11, 13, 17]
valid_len = len(factors)
valid_sequences  = []
total = 0

# Checks for a 3-digit number with 3 unique digits
def not_unique(digits):
  return (digits[0] == digits[1]) or (digits[1] == digits[2]) or (digits[0] == digits[2])


# For each of the prime numbers, generate all valid triples that have unique digits
for i in xrange(0 ,len(factors)):
  current_map = {}
  for j in xrange(factors[i], 1000, factors[i]):
    digits = str(j).zfill(3)

    # Prune those numbers that have non-unique digits
    if not_unique(digits):
      continue

    # current_map is of the form {'d1d2':[list of all possible valid d3s], ...}
    if digits[:2] not in current_map:
      current_map[digits[:2]] = [digits[2]]
    else:
      current_map[digits[:2]].append(digits[2])

  valid_sequences.append(current_map)


# Checks each triple starting with the 3 most significant digits
# Get the last two digits, and find all the valid values for the next one digit
# Perform recursively
def get_matches_starting_with(sequence, index):
  global total
  if index == valid_len:
    print 'Valid number: %s' % sequence
    total += int(sequence)
  else:
    pair = sequence[-2:]
    if pair in valid_sequences[index]:
      for digit in valid_sequences[index][pair]:
        if not digit in sequence:
          get_matches_starting_with(sequence + digit, index + 1)

all_matches = []
for pair in valid_sequences[0]:
  if pair[0] == '0':
      continue
  for digit in valid_sequences[0][pair]:
    triple = pair + digit
    all_matches.append(get_matches_starting_with(triple, 1))

print 'Total: %d' % total

您可能希望运行解决方案这里,并在中间步骤打印值以查看发生了什么。

仍然有很多机会来削减探索的州的数目。你的方法把它从3265920降到了大约3000。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40091852

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档