(Crossed out 44 is still 44.) Thanks to Fireflame241 for saving a byte!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Try it online!
There is exactly one number between 0
and P-1
which is an inverse of 10
. But if that inverse u
happens to be greater than P/2
, then (u-P)
is also an inverse, and has a smaller absolute value than u
. So it turns out that we're really looking for the unique number x
between -P/2
and P/2
which is an inverse of 10
.
The code above does exactly that, starting at (the floor of) P/2
, and stepping
downward until an inverse is reached. This must happen for some number greater than -P/2
so long as P
is a prime greater than 10
. More precisely, it will terminate if and only if P
is coprime to 10
.
Edit: It actually turns out that x
is guaranteed to be between -P/3
and P/3
, so the current version starts at P/3
and steps down from there. See the section labeled Improved Bound for an explanation of this.
Mathematical explanation
It was not immediately obvious to me why the divisibility test worked. Here's an explanation, in case anyone else was wondering.
อนุญาต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
โมดูโล
Now suppose N
is a nonnegative integer whose last digit is d
, so N = 10c + d.
We have a chain of equivalent statements:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Usefulness?
ฉันยังสงสัยด้วยว่าการทดสอบการหาร (ให้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
if และเพียงถ้า(-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
Now, we know that the inverses of 10
modulo P
all differ by multiples of P
, so we can take the integer u
and either add or subtract multiples of P
at will, and the result will always still be an inverse of 10
modulo P
. Suppose we choose to subtract P
from u
: we get
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
In other words, decreasing (respectively, increasing) u
by P
corresponds to decreasing (increasing) k
by 10
. We wish to add/subtract multiples of P
from u
until the left-hand side is minimized in absolute value; but the left-hand side is minimized exactly when the right-hand side is minimized, and so we want to add/subtract 10
from k
until the right-hand side is minimized in absolute value.
แต่เรารู้ว่าเรื่องนี้จะเกิดขึ้นเมื่อk
อยู่ระหว่าง-5
และ5
และดังนั้นจึง (ตั้งแต่k
ค่อนข้างสำคัญในการ10
) วิธีนี้k
เป็นทั้ง-3
, -1
, หรือ1
3
(นี่คือเนื้อหาของความคิดเห็นของ @ Neil ภายใต้ OP ขอบคุณ Neil! )
ดังนั้นเมื่อ|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
)
Therefore the largest that |x|/P
ever gets is 3/10 + 1/(10*13)
, because P=13
is the first prime for which we have k=3
, and among those with k=3
, the 1/(10P)
term is largest when P
is smallest (i.e., at P=13
). Therefore, for all P
, we also have |x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. This explains why in the above code we can initialize at i = P/3
rather than having to start at P/2
.
Further, the bounds in the Usefulness section above can now be improved.
Lemma: Let N = 10c + d
where c > 0
and 0 <= d <= 9
. Then c + d|x| < N/10 + 9(3P + 1)/10
. (Note the strict inequality.)
Proof of Lemma: by cases. Case I: d = 0
, so N = 10c
. Then c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.
Case II: 0 < d <= 9
. Then 10c = N - d < N
, so c < N/10
. Therefore c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.
Thus, if N > 3P
(and N = 10c + d
as before), then
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
So, if N > 3P
then c + d|x| < N
.
Therefore, we only have to find P
, 2P
and 3P
, along with x
. Given N > 0
, while N > 3P
, we replace N
by |c + dx|
, which decreases N
. Eventually we'll get N <= 3P
; at that point we stop and check whether N
is equal to any of the numbers 0
, P
, 2P
, or 3P
.
We can't do better than 3P
in general. For example suppose P = 13
and N = 39
, so x = 4
. Then replacing N
by dx + c = 9(4) + 3
leaves N
unchanged.
x
ในค่าสัมบูรณ์ซึ่ง10*x-1
สามารถหารด้วยอินพุตได้