我的解决方案的基本思想是,您首先生成数字到可以组成它们的数字的映射,因此0 可以由 0+0 或 1+9、2+8 等组成。(但在这种情况下,您必须在下一步记住一个携带的 1 )。然后您从最小的数字开始,并使用该代码检查形成第一位数字的每种可能方式(这为您提供了数字的第一位和最后一位数字的候选者,它们与其相反的总和为您提供输入数字)。然后你移动第二个数字并尝试那些。通过同时检查最后一位和第一位数字可以大大改进此代码,但是由于携带的1,它变得复杂。
import math
candidates = {}
for a in range(10):
for b in range(10):
# a, b, carry
candidates.setdefault((a + b) % 10, []).append((a, b, (a + b) // 10))
def sum_of_reversed_numbers(num):
# We reverse the digits because Arabic numerals come from Arabic, which is
# written right-to-left, whereas English text and arrays are written left-to-right
digits = [int(d) for d in str(num)[::-1]]
# result, carry, digit_index
test_cases = [([None] * len(digits), 0, 0)]
if len(digits) > 1 and str(num).startswith("1"):
test_cases.append(([None] * (len(digits) - 1), 0, 0))
results = []
while test_cases:
result, carry, digit_index = test_cases.pop(0)
if None in result:
# % 10 because if the current digit is a 0 but we have a carry from
# the previous digit, it means that the result and its reverse need
# to actually sum to 9 here so that the +1 carry turns it into a 0
cur_digit = (digits[digit_index] - carry) % 10
for a, b, new_carry in candidates[cur_digit]:
new_result = result[::]
new_result[digit_index] = a
new_result[-(digit_index + 1)] = b
test_cases.append((new_result, new_carry, digit_index + 1))
else:
if result[-1] == 0 and num != 0: # forbid 050 + 050 == 100
continue
i = "".join(str(x) for x in result)
i, j = int(i), int(i[::-1])
if i + j == num:
results.append((min(i, j), max(i, j)))
return results if results else None
我们可以通过预先计算从 0 到 10ⁿ 的所有数字的总和以及它们的反向并将它们存储在一个名为 correct 的列表的字典中来检查上面的代码(一个列表,因为有很多方法可以形成相同的数字,例如 11+11 == 02 + 20),这意味着我们有 10ⁿ⁻¹ 的正确答案,我们可以用它来检查上述函数。顺便说一句,如果您经常使用少量数字执行此操作,那么这种预先计算的方法会更快,但会消耗内存。
如果这段代码什么也没打印,说明它可以工作(或者你的终端坏了:))
correct = {}
for num in range(1000000):
backwards = int(str(num)[::-1])
components = min(num, backwards), max(num, backwards)
summed = num + backwards
correct.setdefault(summed, []).append(components)
for i in range(100000):
try:
test = sum_of_reversed_numbers(i)
except Exception as e:
raise Exception(i) from e
if test is None:
if i in correct:
print(i, test, correct.get(i))
elif sorted(test) != sorted(correct[i]):
print(i, test, correct.get(i))