সংখ্যাগুলি পোস্ট করার জন্য খুব বড়, সুতরাং এখানে তারা পাস্তবিনে রয়েছে: নাম্বার 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)
Triplets আমরা এখান থেকে ডিজিটের পরিবর্তন (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 এটা বেহুদা ছিল একটি না তাই-সাশ্রয়ী বন্দর।