Python 2。
数字を構成するのでかなり効率的です(最も内側のループは合計4570回実行されます)。少し(201文字)ゴルフしたのでかなり短いですが、これについて説明したいのか本当にわかりません:)
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))
ただし、返される値はかなり独特です。w
空のタプルを指定して呼び出すと、10タプルのイテレータが作成されます。これら10組は、残念ながらの二つの数字の桁である後方と交互すなわちタプル
(2, 0, 8, 3, 7, 4, 9, 1, 6, 5)
数値51430および69782を表します。
テスト:
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
これはゴルフされていないバージョンです:
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