Con trăn 2.
Nó khá hiệu quả vì nó xây dựng các con số (vòng lặp bên trong nhất được thực hiện tổng cộng 4570 lần) và khá ngắn vì tôi đã chơi golf một chút (201 ký tự), nhưng tôi không thực sự chắc chắn muốn giải thích điều này :)
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))
Tuy nhiên, các giá trị được trả về khá đặc biệt: gọi w
với một bộ dữ liệu trống và bạn nhận được một bộ lặp gồm 10 bộ. 10 bộ dữ liệu này là chữ số của hai số, than ôi ngược và xen kẽ , tức là bộ
(2, 0, 8, 3, 7, 4, 9, 1, 6, 5)
đại diện cho các số 51430 và 69782.
Kiểm tra:
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
Đây là phiên bản chưa được chỉnh sửa:
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