(Coret 44 masih 44.) Terima kasih kepada Fireflame241 karena telah menghemat satu byte!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Cobalah online!
Hanya ada satu angka di antara 0
dan P-1
yang merupakan kebalikan dari 10
. Tetapi jika kebalikan itu u
terjadi lebih besar dari P/2
, maka (u-P)
juga kebalikannya, dan memiliki nilai absolut yang lebih kecil dari u
. Jadi ternyata kami benar-benar mencari angka unik di x
antara -P/2
dan P/2
yang merupakan kebalikannya 10
.
Kode di atas melakukan hal itu, mulai dari (lantai) P/2
, dan melangkah ke bawah hingga kebalikannya tercapai. Ini harus terjadi untuk beberapa nomor lebih besar dari -P/2
asalkan P
prima lebih besar dari 10
. Lebih tepatnya, itu akan berakhir jika dan hanya jika P
merupakan coprime 10
.
Sunting: Ini sebenarnya ternyata x
dijamin antara -P/3
dan P/3
, jadi versi saat ini dimulai pada P/3
dan turun dari sana. Lihat bagian berlabel Improved Bound untuk penjelasannya.
Penjelasan matematis
Tidak segera jelas bagi saya mengapa tes keterbelahan bekerja. Inilah penjelasan, kalau-kalau ada orang lain yang bertanya-tanya.
Membiarkan P
menjadi prima, lebih besar dari 10
, yang digit terakhirnya adalah b
. Jadi
P = 10a + b
dimana a > 0
, dan 0 <= b < 10
. Bahkan b
adalah baik 1
, 3
, 7
, atau 9
, karena lebih besar perdana dari 10
keharusan akhir di salah satu digit tersebut.
Sekarang misalkan bx + a = 0 (mod P)
. Kemudian
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Karena P
prima, bilangan bulat mod P
adalah domain integral . Jadi b = 0 (mod P)
, atau 1 - 10x = 0 (mod P)
.
Kita tahu 0 <= b < 10 < P
, jadi kalau b = 0 (mod P)
begitu b = 0
. Tapi kami mengatakan b
yang baik 1
, 3
, 7
, atau 9
, jadi ini adalah mustahil. Karena itu 1 - 10x = 0 (mod P)
, begitu 10x = 1 (mod P)
. Dengan kata lain, x
adalah kebalikan dari 10
, modulo P
.
Sekarang anggaplah N
adalah bilangan bulat non-negatif yang digit terakhirnya d
, jadi N = 10c + d.
Kami memiliki rantai pernyataan yang setara:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Kegunaan?
Saya juga bertanya-tanya apakah tes keterbagian (diberikan N = 10c + d
, ganti N
dengan dx + c
) akan benar-benar produktif dalam praktik. Atau setidaknya, apakah itu dapat diandalkan menggantikan N
dengan angka yang lebih kecil dari N
(dalam nilai absolut)?
Misalkan N = 10c + d
, di mana c >= 0
dan 0 <= d < 10
. Oleh karena itu 10c = N - d <= N
. Dengan ketimpangan segitiga,
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Jadi kalau 5P <= 9N/10
begitu |c + dx| < N
.
Khususnya, jika N >= 6P
, maka |c + dx| < N
. Dengan demikian, mengingat P
kita mulai dengan menghitung 2P
, 3P
, ..., 6P
, bersama dengan x
. Kemudian diberikan N
, kami menjalankan uji dibagi berulang kali sampai kita mencapai angka kurang dari atau sama dengan 6P
, dan memeriksa apakah hasilnya adalah salah satu nomor 0
, P
, 2P
, ..., 6P
.
(Tentu saja, setiap kali kita mencapai angka negatif, kita menggantinya dengan nilai absolutnya, yang baik-baik saja karena q
dapat dibagi dengan P
jika dan hanya jika (-q)
ada.)
Peningkatan Terikat
Saya perhatikan bahwa |x|/P
sepertinya tidak pernah dekat 1/2
. Bahkan sepertinya itu selalu kurang dari 1/3
... atau setelah diperiksa lebih dekat, selalu sangat dekat dengan salah satu 1/10
atau 3/10
. Yang terbesar yang pernah ada tampaknya 4/13
(yang terjadi ketika P=13
danx=4
). Mengapa ini terjadi?
Membiarkan u
menjadi bilangan bulat dan anggap itu 10u = kP + 1
untuk bilangan bulat k
, jadi u
adalah kebalikan dari 10
, modulo P
. Kemudian kita juga tahu bahwa k
itu relatif prima 10
, karena k(-P)
setara dengan 1
modulo 10
.
Sekarang, kita tahu bahwa invers dari 10
modulo P
semuanya berbeda berdasarkan kelipatan P
, sehingga kita dapat mengambil bilangan bulat u
dan menambah atau mengurangi kelipatan P
sesuka hati, dan hasilnya akan selalu menjadi kebalikan dari 10
modulo P
. Misalkan kita memilih untuk mengurangi P
dari u
: kita mendapatkan
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
Dengan kata lain, penurunan (masing-masing, meningkatkan) u
oleh P
bersesuaian dengan penurunan (peningkatan) k
oleh 10
. Kami ingin menambah / mengurangi kelipatan dari P
dari u
sampai sisi kiri diminimalkan dalam nilai absolut; tetapi sisi kiri diminimalkan tepat ketika sisi kanan diminimalkan, dan oleh karena itu kami ingin menambahkan / mengurangi 10
dari k
sampai sisi kanan diminimalkan dalam nilai absolut.
Tapi kita tahu bahwa ini akan terjadi ketika k
adalah antara -5
dan 5
, dan karena itu (karena k
relatif prima untuk 10
) berarti ini k
adalah baik -3
, -1
, 1
, atau 3
. (Ini adalah isi dari komentar @ Neil di bawah OP. Terima kasih, Neil! )
Jadi ketika |u|
diminimalkan (yaitu, u=x
), kita akan memiliki x/P = u/P = k/10 + 1/(10P)
, di mana k
adalah baik -3
, -1
, 1
, atau 3
. Oleh karena itu |x|/P <= 3/10 + 1/(10P)
. Setara |x| <= (3P + 1)/10
,.
Lebih jauh, ketidaksetaraan ini sangat ketat pada P=11
, karena pada saat P=11
kita miliki x=-1
dan k=-1
. Yang terkecil P
yang dimiliki kesetaraan adalah P=13
(di mana x=4
dan k=3
).
Oleh karena itu yang terbesar yang |x|/P
pernah didapat adalah 3/10 + 1/(10*13)
, karena P=13
merupakan perdana pertama yang kita miliki k=3
, dan di antara mereka yang memiliki k=3
, 1/(10P)
istilah itu terbesar ketika P
terkecil (yaitu, pada P=13
). Karena itu, untuk semua P
, kami juga punya |x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. Ini menjelaskan mengapa dalam kode di atas kita dapat menginisialisasi i = P/3
daripada harus mulai P/2
.
Selanjutnya, batas-batas di bagian Kegunaan di atas sekarang dapat ditingkatkan.
Lemma : Biarkan di N = 10c + d
mana c > 0
dan 0 <= d <= 9
. Lalu c + d|x| < N/10 + 9(3P + 1)/10
. (Perhatikan ketimpangan yang ketat.)
Bukti Lemma: berdasarkan kasus. Kasus I:, d = 0
jadi N = 10c
. Lalu c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.
Kasus II: 0 < d <= 9
. Lalu 10c = N - d < N
, begitu c < N/10
. Oleh karena itu c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.
Jadi, jika N > 3P
(dan N = 10c + d
seperti sebelumnya), maka
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
Jadi, kalau N > 3P
begitu c + d|x| < N
.
Karena itu, kita hanya perlu menemukan P
, 2P
dan 3P
, bersama dengan x
. Mengingat N > 0
, sementara N > 3P
, kami ganti N
dengan |c + dx|
, yang berkurang N
. Akhirnya kita akan mendapatkannya N <= 3P
; pada saat itu kami berhenti dan memeriksa apakah N
sama dengan salah satu nomor 0
, P
, 2P
, atau 3P
.
Kita tidak bisa berbuat lebih baik daripada 3P
secara umum. Misalnya, anggaplah P = 13
dan N = 39
begitu x = 4
. Kemudian ganti N
dengan dx + c = 9(4) + 3
daun N
tidak berubah.
x
nilai absolut terkecil di mana10*x-1
dapat dibagi oleh input.