संख्याएं पोस्ट करने के लिए बहुत बड़ी हैं, इसलिए यहां वे पास्टबिन पर हैं: संख्या 1 , संख्या 2 ।
पहला नंबर 600^2 = 360000
वालों का है। निम्नलिखित परिवर्तनों को छोड़कर दूसरी संख्या समान है:
Positions to change to "2": 605, 1811, 3001, 6603
Positions to change to "4": 1805, 3003, 57348, 208895
Positions to change to "5": 602, 1201, 2405, 3004
Positions to change to "6": 1203, 1802
Positions to change to "7": 12, 609, 5401, 7200
Positions to change to "8": 1, 2, 4, 6, 600, 1200, 1808, 2400, 3600, 4803
दोनों को हैश 271088937720654725553339294593617693056
।
व्याख्या
आइए कोड के पहले भाग पर एक नज़र डालें:
lW% e# Read input number as string, and reverse
600/ e# Split every 600 digits, forming a 2D array
_z e# Duplicate and zip, swapping rows and columns
{ }% e# For both arrays...
JfbDb e# Find sum of S[i][j]*13^i*19^j, where S are the character values
e# and the indices are from right to left, starting at 0.
GK# e# Take modulo 16^20
... ... e# (Rest of code irrelevant)
इसलिए यदि हम दो इनपुट नंबर पा सकते हैं ताकि प्रारंभिक 600-वाइड एरे और ज़िप्ड ऐरे दोनों के लिए S[i][j]*13^i*19^j
एक ही मॉडुलो एक ही 16^20
हो।
चीजों को थोड़ा आसान बनाने के लिए, हम केवल 600^2 = 360000
-डिजिट इनपुट संख्याओं पर विचार करेंगे , ताकि 600-वाइड सरणी अंकों के 600 से 600 वर्ग के बराबर हो। यह चीजों को कल्पना करना आसान बनाता है, और तब से मान्य है 10^360000 ~ 2^(2^20.19) < 2^(2^30)
। आगे भी चीजों को सरल बनाने के लिए, हम केवल ऐसे इनपुट स्ट्रिंग्स पर विचार करेंगे जिनके अंक वर्ग मुख्य विकर्ण के साथ सममित है, ताकि मूल सरणी और ज़िपित सरणी समान हो। यह हमें शुरुआती स्ट्रिंग रिवर्सल और राइट-टू-लेफ्ट इंडेक्स नंबरिंग को अनदेखा करने की भी अनुमति देता है, जो एक दूसरे को रद्द करते हैं।
हमें शुरू करने के लिए, हम पहले नंबर पर जा 360000
सकते हैं। दूसरे नंबर को प्राप्त करने के लिए, हम कुछ अंकों को बदलकर इसे संशोधित करना चाहते हैं, ताकि अंक 16^20
वर्ग के समरूपता को संरक्षित करते हुए रकम एक ही मॉड्यूल हो । हम इसे तीनों की सूची प्राप्त करके पूरा करते हैं (i, j, k)
ताकि
sum of k*(13^i 19^j + 19^i 13^j) == 0 mod 16^20
कहां 1 <= k <= 8
से अंक 1 को बढ़ाने की राशि है (यानी 2 से 9 तक एक अंक में बदलकर - हम 0 को शामिल कर सकते हैं लेकिन हमें इसकी आवश्यकता नहीं थी) और 0 <= i < j < 600
सूचकांक जोड़े हैं।
एक बार जब हम है (i, j, k)
तीनो, हम से कम अंक बदलने (i, j)
और (j, i)
करने के लिए 1+k
दूसरा नंबर पाने के लिए। ट्रिपल को लालची बैकग्राउंडिंग एल्गोरिथ्म का उपयोग करते हुए पाया गया, और अंक वर्ग के ऊपर दूसरे नंबर के लिए ऐसा दिखता है:
188181811111711 ...
815112111711111 ...
851611111111111 ...
116114118112111 ...
811115111111111 ...
121451111111111 ...
811111111111111 ...
111111111111111 ...
111811111111111 ...
171111111111111 ...
111111111111111 ...
111211111111111 ...
711111111111111 ...
111111111111111 ...
111111111111111 ...
............... .
............... .
............... .
उदाहरण के लिए, (i, j, k) = (0, 1, 7)
अंकों (0, 1)
(स्थिति 600*0 + 1 = 1
) और (1, 0)
(स्थिति 600*1 + 0 = 600
) को बदलने से मेल खाती है 1 + 7 = 8
।
यहां पायथन 3 में बैकट्रैकर है, हालांकि निकट निरीक्षण से पता चला है कि हम बहुत भाग्यशाली थे, क्योंकि वास्तव में कोई बैकट्रैकिंग नहीं हुई थी:
n = 16**20
L = [(k *(pow(13,i,n)*pow(19,j,n) + pow(19,i,n)*pow(13,j,n)) % n, i, j, k)
for i in range(600) for j in range(600) for k in range(1, 9) if i < j]
L.sort(reverse=True)
stack = [(n, 0, [])]
while stack:
k, index, result = stack.pop()
if k == 0:
print(result)
break
if index == len(L):
continue
stack.append((k, index+1, result)) # Don't include triplet
if L[index][0] <= k:
stack.append((k - L[index][0], index+1, result + [L[index][1:]])) # Include
एक बोनस के लिए, यहाँ पायथन 3 में हैश का एक नहीं-तो-कुशल बंदरगाह है। यह बेकार था।