(Cancellati 44 sono ancora 44.) Grazie a Fireflame241 per aver salvato un byte!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Provalo online!
C'è esattamente un numero tra 0
e P-1
che è un inverso di 10
. Ma se quell'inverso u
sembra essere maggiore di P/2
, allora (u-P)
è anche un inverso e ha un valore assoluto minore di u
. Quindi si scopre che stiamo davvero cercando il numero univoco x
tra -P/2
e P/2
che è un contrario di10
.
Il codice sopra fa esattamente questo, iniziando da (il piano di) P/2
, e scendendo verso il basso fino a raggiungere un inverso. Questo deve accadere per un numero maggiore di -P/2
fino a quando P
è un numero maggiore di 10
. Più precisamente, terminerà se e solo se P
è coprime10
.
Modifica: si scopre che x
è garantito che si trova tra -P/3
e P/3
, quindi la versione corrente inizia alle P/3
e scende da lì. Vedi la sezione etichettata Migliorato per una spiegazione di questo.
Spiegazione matematica
Non è stato immediatamente ovvio per me perché il test di divisibilità ha funzionato. Ecco una spiegazione, nel caso qualcuno si stesse chiedendo.
Sia P
un numero primo, maggiore di 10
, la cui ultima cifra è b
. così
P = 10a + b
dove a > 0
e 0 <= b < 10
. Infatti b
è o 1
, 3
, 7
o 9
, perché una maggiore privilegiata di 10
fine mosto in una di queste cifre.
Ora supponiamo bx + a = 0 (mod P)
. Poi
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Poiché P
è primo, gli interi mod P
sono un dominio integrale . Quindi b = 0 (mod P)
, oppure 1 - 10x = 0 (mod P)
.
Lo sappiamo 0 <= b < 10 < P
, quindi se b = 0 (mod P)
allora b = 0
. Ma abbiamo detto b
è o 1
, 3
, 7
o 9
, quindi questo è impossibile. Pertanto 1 - 10x = 0 (mod P)
, così 10x = 1 (mod P)
. In altre parole, x
è l'inverso di 10
, modulo P
.
Supponiamo ora che N
sia un numero intero non negativo la cui ultima cifra è d
, quindi N = 10c + d.
abbiamo una catena di istruzioni equivalenti:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Utilità?
Mi chiedevo anche se il test di divisibilità (dato N = 10c + d
, sostituito N
da dx + c
) sarebbe effettivamente produttivo nella pratica. O almeno, sostituisce in modo affidabile N
un numero inferiore a N
(in valore assoluto)?
Supponiamo N = 10c + d
, dove c >= 0
e 0 <= d < 10
. Pertanto 10c = N - d <= N
. Per la disuguaglianza del triangolo,
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Quindi se 5P <= 9N/10
, allora |c + dx| < N
.
In particolare, se N >= 6P
, allora |c + dx| < N
. Così, dato P
iniziamo calcolando 2P
, 3P
, ..., 6P
, insieme x
. Poi dato N
, si corre il test divisibilità ripetutamente fino a raggiungere un numero minore o uguale a 6P
, e controllare se il risultato è uno qualsiasi dei numeri 0
, P
, 2P
, ..., 6P
.
(Ovviamente, ogni volta che raggiungiamo un numero negativo, lo sostituiamo con il suo valore assoluto, che va bene poiché q
è divisibile per P
se e solo se lo (-q)
è.)
Vincolato migliorato
Ho notato che |x|/P
non sembrava essere mai vicino 1/2
. In effetti sembrava che fosse sempre meno di 1/3
... o ad un esame più attento, era sempre molto vicino a uno 1/10
o l'altro 3/10
. Il più grande che sia mai sembrato essere 4/13
(cosa che succede quando P=13
e x=4
). Perché dovrebbe essere?
Sia u
un numero intero e supponiamo che 10u = kP + 1
per un numero intero k
, così u
è un inverso di 10
, modulo P
. Quindi sappiamo anche che k
è relativamente importante 10
, poiché k(-P)
equivale a 1
modulo 10
.
Ora sappiamo che le inverse di 10
modulo P
differiscono tutte per multipli di P
, quindi possiamo prendere l'intero u
e aggiungere o sottrarre multipli di P
a piacimento, e il risultato sarà sempre un inverso di 10
modulo P
. Supponiamo che scegliamo di sottrarre P
da u
: otteniamo
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
In altre parole, diminuire (rispettivamente aumentare) u
di P
corrisponde a diminuire (aumentare) k
di 10
. Desideriamo aggiungere / sottrarre multipli di P
da u
fino a quando il lato sinistro non viene minimizzato in valore assoluto; ma il lato sinistro è ridotto al minimo esattamente quando il lato destro è ridotta al minimo, e quindi vogliamo aggiungere / sottrarre 10
dal k
fino a quando il lato destro è ridotto al minimo in valore assoluto.
Ma sappiamo che questo avverrà quando k
è compreso tra -5
e 5
, e quindi (in quanto k
è relativamente privilegiata per 10
) questo mezzo k
è o -3
, -1
, 1
o 3
. (Questo è il contenuto del commento di @ Neil sotto l'OP. Grazie, Neil! )
Così, quando |u|
è ridotto al minimo (cioè u=x
), avremo x/P = u/P = k/10 + 1/(10P)
, in cui k
è o -3
, -1
, 1
o 3
. Pertanto |x|/P <= 3/10 + 1/(10P)
. Equivalentemente, |x| <= (3P + 1)/10
.
Inoltre, questa disuguaglianza è severa P=11
, perché P=11
abbiamo x=-1
e k=-1
. Il più piccolo P
per cui vale l'uguaglianza è P=13
(dove x=4
e k=3
).
Quindi il più grande che |x|/P
abbia mai ottenuto è 3/10 + 1/(10*13)
, perché P=13
è il primo primo per cui abbiamo k=3
, e tra quelli con k=3
, il 1/(10P)
termine è più grande quando P
è il più piccolo (cioè, a P=13
). Pertanto, per tutti P
, abbiamo anche |x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. Questo spiega perché nel codice sopra possiamo inizializzare i = P/3
piuttosto che dover iniziare da P/2
.
Inoltre, ora è possibile migliorare i limiti nella sezione Utilità sopra.
Lemma : Lascia N = 10c + d
dove c > 0
e 0 <= d <= 9
. Poi c + d|x| < N/10 + 9(3P + 1)/10
. (Nota la disuguaglianza rigorosa.)
Prova di Lemma: per casi. Caso I: d = 0
così N = 10c
. Poi c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.
Caso II: 0 < d <= 9
. Quindi 10c = N - d < N
, quindic < N/10
. Pertanto c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.
Quindi, se N > 3P
(e N = 10c + d
come prima), allora
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
Quindi, se N > 3P
allorac + d|x| < N
.
Pertanto, dobbiamo solo trovare P
, 2P
e 3P
, insieme a x
. Dato N > 0
, mentre N > 3P
, sostituiamo N
con |c + dx|
, che diminuisce N
. Alla fine avremo N <= 3P
; a quel punto ci fermiamo e verificare se N
è uguale a uno qualsiasi dei numeri 0
, P
, 2P
, o 3P
.
Non possiamo fare di meglio che 3P
in generale. Ad esempio supponiamo P = 13
e N = 39
, quindi x = 4
. Quindi sostituendo N
con dx + c = 9(4) + 3
foglie N
invariate.
x
valore assoluto dove10*x-1
è divisibile per l'input.