(44 barré est toujours 44.) Merci à Fireflame241 pour avoir sauvé un octet!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Essayez-le en ligne!
Il y a exactement un nombre entre 0
et P-1
qui est l'inverse de 10
. Mais si cet inverse u
se trouve être supérieur à P/2
, il (u-P)
est également un inverse et a une valeur absolue inférieure à u
. Il s'avère donc que nous recherchons vraiment le nombre unique x
entre -P/2
et P/2
qui est l'inverse de 10
.
Le code ci-dessus fait exactement cela, en commençant à (l'étage de) P/2
et en descendant jusqu'à ce qu'un inverse soit atteint. Cela doit se produire pour un certain nombre supérieur à -P/2
tant P
qu'un nombre premier supérieur à 10
. Plus précisément, il se terminera si et seulement si P
est coprime à 10
.
Edit: Il s'avère que cela x
est garanti entre -P/3
et P/3
, donc la version actuelle commence à P/3
et descend de là. Voir la section intitulée Amélioré lié pour une explication à ce sujet.
Explication mathématique
Il n'était pas immédiatement évident pour moi pourquoi le test de divisibilité fonctionnait. Voici une explication, au cas où quelqu'un d'autre se demanderait.
Soit P
un nombre premier supérieur à 10
dont le dernier chiffre est b
. Donc
P = 10a + b
où a > 0
, et 0 <= b < 10
. En fait b
est soit 1
, 3
, 7
ou 9
, parce qu'une prime supérieure à la 10
fin de l' indispensable dans l' un de ces chiffres.
Supposons maintenant bx + a = 0 (mod P)
. alors
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Puisque P
est premier, les entiers mod P
sont un domaine intégral . Alors soit b = 0 (mod P)
, soit 1 - 10x = 0 (mod P)
.
Nous savons 0 <= b < 10 < P
, donc si b = 0 (mod P)
alors b = 0
. Mais nous avons dit b
est soit 1
, 3
, 7
ou 9
, il en est ainsi impossible. Donc 1 - 10x = 0 (mod P)
, donc 10x = 1 (mod P)
. En d'autres termes, x
est l'inverse de 10
, moduloP
.
Supposons maintenant que N
c'est un entier non négatif dont le dernier chiffre est d
, N = 10c + d.
Nous avons donc une chaîne d'instructions équivalentes:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Utilité?
Je me demandais également si le test de divisibilité (donné N = 10c + d
, remplacé N
par dx + c
) serait réellement productif dans la pratique. Ou du moins, est-il remplacé de manière fiable N
par un nombre inférieur à N
(en valeur absolue)?
Supposons N = 10c + d
où c >= 0
et 0 <= d < 10
. Par conséquent 10c = N - d <= N
. Par l'inégalité du triangle,
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Donc si 5P <= 9N/10
, alors |c + dx| < N
.
En particulier, si N >= 6P
, alors |c + dx| < N
. Ainsi, étant donné que P
nous commençons par le calcul 2P
, 3P
..., 6P
ainsi que x
. Ensuite , étant donné N
, nous courons le test de divisibilité à plusieurs reprises jusqu'à ce qu'on atteigne un nombre inférieur ou égal à 6P
, et vérifier si le résultat est l' un des numéros 0
, P
, 2P
, ..., 6P
.
(Bien sûr, chaque fois que nous atteignons un nombre négatif, nous le remplaçons par sa valeur absolue, ce qui est bien car q
est divisible par P
si et seulement si (-q)
est.)
Limite améliorée
J'ai remarqué que cela |x|/P
ne semblait jamais être proche 1/2
. En fait, il semblait que c'était toujours moins que 1/3
... ou à y regarder de plus près, c'était toujours très proche de l'un 1/10
ou de l' autre 3/10
. Le plus gros jamais obtenu semblait être 4/13
(ce qui arrive quand P=13
etx=4
). Pourquoi serait-ce?
Soit u
un entier et supposons que 10u = kP + 1
pour un entier k
, il en u
soit de l'inverse de 10
, modulo P
. Ensuite, nous savons également que k
c'est relativement premier 10
, car k(-P)
est équivalent à 1
modulo 10
.
Maintenant, nous savons que les inverses de 10
modulo P
diffèrent tous par des multiples de P
, nous pouvons donc prendre l'entier u
et soit ajouter ou soustraire des multiples de P
à volonté, et le résultat sera toujours toujours un inverse de 10
modulo P
. Supposons que nous choisissons de soustraire P
de u
: nous obtenons
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
En d'autres termes, une diminution (respectivement une augmentation) u
de P
correspond à une diminution (une augmentation) k
de 10
. Nous souhaitons ajouter / soustraire des multiples de P
de u
jusqu'à ce que le côté gauche soit minimisé en valeur absolue; mais le côté gauche est minimisé exactement lorsque le côté droit est minimisé, et nous voulons donc ajouter / soustraire 10
de k
jusqu'à ce que le côté droit soit minimisé en valeur absolue.
Mais nous savons que cela se produira quand k
est entre -5
et 5
, et donc (depuis k
est relativement premier 10
) ce moyen k
est soit -3
, -1
, 1
ou 3
. (C'est le contenu du commentaire de @ Neil sous le PO. Merci, Neil! )
Ainsi , quand |u|
est réduite au minimum (c. -à u=x
), nous aurons x/P = u/P = k/10 + 1/(10P)
, où k
est soit -3
, -1
, 1
ou 3
. Par conséquent |x|/P <= 3/10 + 1/(10P)
. De manière équivalente, |x| <= (3P + 1)/10
.
De plus, cette inégalité est stricte chez P=11
, car chez P=11
nous nous avons x=-1
et k=-1
. Le plus petit P
pour lequel l'égalité est valable est P=13
(où x=4
et k=3
).
Par conséquent, le plus grand |x|/P
jamais obtenu est 3/10 + 1/(10*13)
, parce que P=13
c'est le premier nombre premier pour lequel nous avons k=3
, et parmi ceux avec k=3
, le 1/(10P)
terme est le plus grand quand il P
est le plus petit (c'est-à-dire, à P=13
). Par conséquent, pour tous P
, nous avons aussi |x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. Cela explique pourquoi dans le code ci-dessus, nous pouvons initialiser à i = P/3
plutôt que d'avoir à commencer par P/2
.
De plus, les limites de la section Utilité ci-dessus peuvent maintenant être améliorées.
Lemme : Soit N = 10c + d
où c > 0
et 0 <= d <= 9
. Alors c + d|x| < N/10 + 9(3P + 1)/10
. (Notez l'inégalité stricte.)
Preuve de lemme: par cas. Cas I: d = 0
oui N = 10c
. Alors c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.
Cas II: 0 < d <= 9
. Alors 10c = N - d < N
, alors c < N/10
. Par conséquent c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.
Ainsi, si N > 3P
(et N = 10c + d
comme précédemment), alors
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
Alors, si N > 3P
alors c + d|x| < N
.
Par conséquent, nous n'avons qu'à trouver P
, 2P
et 3P
, avec x
. Étant donné N > 0
que N > 3P
, nous remplaçons N
par |c + dx|
, ce qui diminue N
. Finalement, nous aurons N <= 3P
; à ce moment - là nous nous arrêtons et vérifier si N
est égal à l' un des numéros 0
, P
, 2P
ou 3P
.
Nous ne pouvons pas faire mieux qu'en 3P
général. Par exemple, supposons que P = 13
et N = 39
ainsi x = 4
. Puis remplaçant N
par des dx + c = 9(4) + 3
feuilles N
inchangées.
x
en valeur absolue où10*x-1
est divisible par l'entrée.