(Закреслено 44 ще 44.) Завдяки Fireflame241 за збереження байта!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Спробуйте в Інтернеті!
Існує рівно одне число між 0і P-1яке є оберненим 10. Але якщо ця обернена величина uбільша за P/2, то (u-P)це також обернена і має менше абсолютне значення, ніж u. Так виходить, що ми дійсно шукаємо унікальне число xміж ними-P/2 і P/2яке є зворотним10 .
Код, що вводиться вище, робить саме це, починаючи з (поверху) P/2і відступаючи доти, доки не буде досягнуто зворотного. Це повинно відбуватися на деяку кількість, більший за той -P/2час, коли Pпрайм більший за 10. Точніше, він припиняється, якщо і лише тодіP є спільним 10.
Редагувати: насправді виявляється, що xвін гарантовано знаходиться між -P/3і P/3, тому поточна версія починається з P/3та знижується звідти. Для пояснення цього див. Розділ з поліпшеною межею .
Математичне пояснення
Мені було не відразу зрозуміло, чому працює тест на подільність. Ось пояснення, на випадок, якщо хтось ще задумався.
Нехай Pбуде простим, більшим за 10, чия остання цифра b. Таким чином
P = 10a + b
де a > 0і 0 <= b < 10. Насправді bабо 1, 3, 7, або 9, так як просте число , більше 10має закінчуватися в одній з цих цифр.
Тепер припустимо bx + a = 0 (mod P). Потім
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Оскільки Pє простим, цілі числа mod Pє цілісною областю . Так чи b = 0 (mod P), або1 - 10x = 0 (mod P) .
Ми знаємо 0 <= b < 10 < P, так, якщо b = 0 (mod P)тоді b = 0. Але ми сказали , bабо 1, 3, 7, або 9, так що це неможливо. Тому 1 - 10x = 0 (mod P)так 10x = 1 (mod P). Іншими словами, xце зворотне значення 10модуля P.
Припустимо N, це невід’ємне ціле число, остання цифра якого є d, тому у N = 10c + d. нас є ланцюжок еквівалентних висловлювань:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Корисність?
Мені було також цікаво чи тест подільності (враховуючи N = 10c + d, замінити Nна dx + c) буде на самому ділі бути продуктивним на практиці. Або, принаймні, чи надійно його замінює Nна число, менше ніжN (в абсолютній величині)?
Припустимо N = 10c + d, де c >= 0і 0 <= d < 10. Тому 10c = N - d <= N. За нерівністю трикутника,
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Таким чином, якщо 5P <= 9N/10, то |c + dx| < N.
Зокрема, якщо N >= 6P, то |c + dx| < N. Таким чином, з огляду на , Pми почнемо з розрахунку 2P, 3P..., 6Pпоряд з x. Потім дається N, ми проводимо тест делімостних кілька разів , поки ми не досягнемо числа менше або дорівнює 6P, і перевірити , є чи результат будь-якої з чисел 0, P, 2P..., 6P.
(Зрозуміло, щоразу, коли ми досягаємо від’ємного числа, ми замінюємо його абсолютним значенням, яке добре, оскільки qділиться на Pтоді і лише тоді, коли (-q)є.)
Поліпшене обмеження
Я помітив, що |x|/Pніколи не здавалося, що поруч 1/2. Насправді здавалося, що це завжди менше, ніж 1/3... або при більш детальному огляді це завжди було дуже близько до 1/10або 3/10. Найбільшим, що коли-небудь було, здавалося, 4/13що буває (коли P=13і коли x=4). Чому це було б?
Нехай uбуде цілим числом, і припустимо, що 10u = kP + 1для деякого цілого числа k, так uце обернено 10модуль P. Тоді ми також знаємо, що kє відносно простим 10, оскільки k(-P)еквівалентно 1модулю10 .
Тепер ми знаємо, що всі звороти 10модуля Pрізняться кратними величинами P, тому ми можемо взяти ціле число uі або додавати, або віднімати кратні Pза бажанням, і результат завжди буде інверсійним за 10модулем P. Припустимо , що ми вибираємо , щоб відняти Pз u: ми отримуємо
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
Іншими словами, зменшення (відповідно, збільшення) uна Pвідповідно зменшується (збільшується) kна 10. Ми хочемо додати / відняти кратні Pз, uпоки ліва частина не буде мінімізована в абсолютній величині; але лівий бік зведений саме тоді, коли правий бік зведений до мінімуму, і тому ми хочемо додавати / віднімати 10з kтих пір, поки правий бік не буде мінімізований в абсолютне значення.
Але ми знаємо , що це станеться , коли kміж -5і 5, і , отже , (так як kвзаємно просте з 10) це означає , що kабо -3, -1, 1або 3. (Це вміст коментаря @ Ніла в рамках ОП. Дякую, Ніл! )
Таким чином , коли |u|мінімізується (тобто u=x), ми будемо мати x/P = u/P = k/10 + 1/(10P), де kабо -3, -1, 1або 3. Тому |x|/P <= 3/10 + 1/(10P). Рівнозначно , |x| <= (3P + 1)/10.
Далі ця нерівність сувора в P=11тому, що в P=11нас є x=-1і k=-1. Найменший розмір, Pна який дотримується рівність, є P=13(де x=4і k=3).
Тому найбільший, що |x|/Pколи-небудь отримує 3/10 + 1/(10*13), тому що P=13це перший прайм, який ми маємо k=3, і серед тих, хто має k=3, 1/(10P)термін найбільший, коли Pнайменший (тобто, в P=13). Тому для всіх у Pнас теж є |x|/P <= 3/10 + 1/130 = 4/13 < 1/3. Це пояснює, чому у наведеному вище коді ми можемо ініціалізуватись, i = P/3а не потрібно починати P/2.
Крім того, межі в розділі Корисність вище можна тепер покращити.
Лема : Нехай N = 10c + dде c > 0і де 0 <= d <= 9. Потім c + d|x| < N/10 + 9(3P + 1)/10. (Зверніть увагу на сувору нерівність.)
Доведення леми: по випадках. Випадок I: d = 0так N = 10c. Потім c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10.
Випадок II: 0 < d <= 9. Тоді 10c = N - d < N, так c < N/10. Томуc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10 . QED.
Таким чином, якщо N > 3P(і N = 10c + dяк і раніше), то
3P + 1 <= N
9(3P + 1)/10 <= 9N/10
N/10 + 9(3P + 1)/10 <= N
c + d|x| < N/10 + 9(3P + 1)/10 <= N
Отже, якщо N > 3Pтоді c + d|x| < N.
Тому нам залишається лише знайти P, 2Pі 3Pразом з x. Враховуючи N > 0, поки N > 3Pми замінюємо Nна |c + dx|, що зменшується N. Врешті-решт ми отримаємо N <= 3P; в цій точці ми зупиняємося і перевірити , є чи Nодно жодному з чисел 0, P, 2Pабо3P .
Ми не можемо зробити краще, ніж 3Pзагалом. Наприклад припустимо P = 13і N = 39так x = 4. Потім замінити Nна dx + c = 9(4) + 3листя Nбез змін.
xза абсолютною величиною, де10*x-1ділиться на вхід.