(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 0e P-1che è un inverso di 10. Ma se quell'inverso usembra 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 xtra -P/2e P/2che è 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/2fino 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/3e P/3, quindi la versione corrente inizia alle P/3e 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 Pun numero primo, maggiore di 10, la cui ultima cifra è b. così
P = 10a + b
dove a > 0e 0 <= b < 10. Infatti bè o 1, 3, 7o 9, perché una maggiore privilegiata di 10fine 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 Psono 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, 7o 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 Nsia 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 Nda dx + c) sarebbe effettivamente produttivo nella pratica. O almeno, sostituisce in modo affidabile Nun numero inferiore a N(in valore assoluto)?
Supponiamo N = 10c + d, dove c >= 0e 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 Piniziamo 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 Pse e solo se lo (-q)è.)
Vincolato migliorato
Ho notato che |x|/Pnon 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/10o l'altro 3/10. Il più grande che sia mai sembrato essere 4/13(cosa che succede quando P=13e x=4). Perché dovrebbe essere?
Sia uun numero intero e supponiamo che 10u = kP + 1per 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 1modulo 10.
Ora sappiamo che le inverse di 10modulo Pdifferiscono tutte per multipli di P, quindi possiamo prendere l'intero ue aggiungere o sottrarre multipli di Pa piacimento, e il risultato sarà sempre un inverso di 10modulo P. Supponiamo che scegliamo di sottrarre Pda u: otteniamo
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
In altre parole, diminuire (rispettivamente aumentare) udi Pcorrisponde a diminuire (aumentare) kdi 10. Desideriamo aggiungere / sottrarre multipli di Pda ufino 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 10dal kfino a quando il lato destro è ridotto al minimo in valore assoluto.
Ma sappiamo che questo avverrà quando kè compreso tra -5e 5, e quindi (in quanto kè relativamente privilegiata per 10) questo mezzo kè o -3, -1, 1o 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, 1o 3. Pertanto |x|/P <= 3/10 + 1/(10P). Equivalentemente, |x| <= (3P + 1)/10.
Inoltre, questa disuguaglianza è severa P=11, perché P=11abbiamo x=-1e k=-1. Il più piccolo Pper cui vale l'uguaglianza è P=13(dove x=4e k=3).
Quindi il più grande che |x|/Pabbia 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/3piuttosto che dover iniziare da P/2.
Inoltre, ora è possibile migliorare i limiti nella sezione Utilità sopra.
Lemma : Lascia N = 10c + ddove c > 0e 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 = 0così 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 + dcome 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 > 3Pallorac + d|x| < N .
Pertanto, dobbiamo solo trovare P, 2Pe 3P, insieme a x. Dato N > 0, mentre N > 3P, sostituiamo Ncon |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 3Pin generale. Ad esempio supponiamo P = 13e N = 39, quindi x = 4. Quindi sostituendo Ncon dx + c = 9(4) + 3foglie Ninvariate.
xvalore assoluto dove10*x-1è divisibile per l'input.