Python 2.
Ini cukup efisien karena ia membangun angka-angka (loop paling dalam dieksekusi total 4570 kali) dan cukup pendek karena saya bermain golf sedikit (201 karakter), tapi saya tidak begitu yakin saya ingin menjelaskan ini :)
p=lambda t,a,d:((x,y)for x in range(10)for y in[(t-x-a)%10]if(x not in d)&(y not in d)and x-y)
w=lambda s:[s]if len(s)==10and s[:5]<s[5:]else(m for n in p(2-len(s)/2%2,sum(s[-2:])/10,s)for m in w(s+n))
Nilai yang dikembalikan cukup aneh, meskipun: panggilan w
dengan tuple kosong, dan Anda mendapatkan iterator 10-tupel. 10 tupel ini adalah digit dari dua angka, sayangnya mundur dan bergantian , yaitu tupel
(2, 0, 8, 3, 7, 4, 9, 1, 6, 5)
mewakili angka 51430 dan 69782.
Uji:
result = list(w(()))
assert len(set(result)) == 192 # found all values
assert len(result) == 192 # and no dupes
for digits in result:
assert all(0 <= d <= 9 for d in digits) # real digits -- zero through nine
assert len(set(digits)) == 10 # all digits distinct
n1 = int("".join(map(str, digits[9::-2])))
n2 = int("".join(map(str, digits[8::-2])))
assert n1 + n2 == 121212 # sum is correct
Ini adalah versi yang tidak dikoleksi:
ppcalls = 0 # number of calls to possiblePairs
ppyields = 0 # number of pairs yielded by possiblePairs
ppconstructed = 0 # number of construced pairs; this is the number
# of times we enter the innermost loop
def possiblePairs(theirSumMod10, addition, disallowed):
global ppcalls, ppyields, ppconstructed
ppcalls += 1
for a in range(10):
b = (theirSumMod10 - a - addition) % 10
ppconstructed += 1
if a not in disallowed and b not in disallowed and a != b:
ppyields += 1
yield (a, b)
def go(sofar):
if len(sofar) == 10:
if sofar[:5] < sofar[5:]: # dedupe
yield sofar
digitsum = 2 - (len(sofar) / 2) % 2 # 1 or 2, alternating
for newpair in possiblePairs(digitsum, sum(sofar[-2:]) / 10, sofar):
for more in go(sofar + newpair):
yield more
list(go(())) # iterate
print ppcalls # 457
print ppyields # 840
print ppconstructed # 4570