( Riscado 44 ainda é 44.) Obrigado a Fireflame241 por salvar um byte!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Experimente online!
Existe exatamente um número entre 0e do P-1qual é inverso 10. Mas se esse inverso ufor maior que P/2, então (u-P)também será um inverso e terá um valor absoluto menor que u. Assim, verifica-se que estamos realmente olhando para o número único xentre -P/2e P/2que é o inverso da 10.
O código acima faz exatamente isso, começando em (o andar de) P/2e descendo até que um inverso seja alcançado. Isso deve acontecer para um número maior que -P/2o tempo que Pé um primo maior que 10. Mais precisamente, ele terminará se e somente se Pfor coprime para 10.
Editar: Na verdade, xé garantido que está entre -P/3e P/3, portanto, a versão atual começa em P/3e desce a partir daí. Consulte a seção Limite aprimorado para obter uma explicação sobre isso.
Explicação matemática
Não ficou imediatamente óbvio para mim por que o teste de divisibilidade funcionou. Aqui está uma explicação, caso alguém mais esteja se perguntando.
Deixei P Ser um primo, maior que 10, cujo último dígito é b. portanto
P = 10a + b
em que a > 0, e 0 <= b < 10. Na verdade bé tanto 1,3 , 7ou 9, porque uma maior nobre do que10 final must em um desses dígitos.
Agora suponha bx + a = 0 (mod P). Então
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Como Pé primo, os números inteiros mod Psão um domínio integral . Então b = 0 (mod P), ou1 - 10x = 0 (mod P) .
Nós sabemos 0 <= b < 10 < P, então se b = 0 (mod P)então b = 0. Mas nós dissemos bé ou 1, 3, 7ou 9, então isso é impossível. Portanto 1 - 10x = 0 (mod P), então10x = 1 (mod P) . Em outras palavras, xé o inverso do 10módulo P.
Agora, suponha que Nseja um número inteiro não negativo cujo último dígito seja d, portanto, N = 10c + d. temos uma cadeia de instruções equivalentes:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Utilidade?
Também estava me perguntando se o teste de divisibilidade (dado N = 10c + d, substituído Npor dx + c) seria realmente produtivo na prática. Ou pelo menos, ele substitui com segurança Npor um número menor que N(em valor absoluto)?
Suponha N = 10c + d, onde c >= 0e 0 <= d < 10. Portanto 10c = N - d <= N. Pela desigualdade do triângulo,
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Assim se 5P <= 9N/10, então |c + dx| < N.
Em particular, se N >= 6P, então |c + dx| < N. Assim, dado Pque começamos calculando 2P, 3P, ..., 6P, juntamente com x. Então dado N, corremos o teste de divisibilidade repetidamente até chegar a um número menor ou igual a 6P, e verificar se o resultado é qualquer um dos números 0, P, 2P, ..., 6P.
(Obviamente, sempre que atingimos um número negativo, o substituímos por seu valor absoluto, o que é bom, pois qé divisível por Pse e somente se(-q) é.)
Limite melhorado
Percebi que |x|/Pnunca parecia estar perto 1/2. Na verdade, parecia que sempre foi menos do que 1/3... ou após um exame mais detalhado, sempre foi muito próximo de um 1/10ou outro 3/10. A maior já parecia ser 4/13(o que acontece quando P=13e x=4). Por que isso seria?
Seja uum número inteiro e suponha que, 10u = kP + 1para algum número inteiro k, o uinverso seja o 10módulo P. Então também sabemos que isso ké relativamente primordial 10, já que k(-P)é equivalente a 1módulo 10.
Agora, sabemos que todos os inversos do 10módulo Pdiferem por múltiplos de P, para que possamos pegar o número inteiro ue adicionar ou subtrair múltiplos Pà vontade, e o resultado sempre será um inverso do 10módulo P. Suponha que nós escolhemos para subtrair Pa partir de u: obtemos
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
Em outras palavras, diminuir (respectivamente, aumentar) uem Pcorresponde a diminuir (aumentar) kem 10. Queremos adicionar / múltiplos subtrair de Ppartir uaté que o lado esquerdo é minimizado em valor absoluto; mas o lado esquerdo é minimizado exatamente quando o lado direito é minimizado e, por isso, queremos adicionar / subtrair 10dek até que o lado direito seja minimizado em valor absoluto.
Mas nós sabemos que isso vai acontecer quando kestiver entre -5e 5, e, portanto, (uma vez que ké relativamente privilegiada para 10) este meio ké ou -3, -1, 1ou 3. (Este é o conteúdo do comentário de @ Neil no OP. Obrigado, Neil! )
Assim, quando |u|é minimizado (ou seja, u=x), teremos x/P = u/P = k/10 + 1/(10P), onde ké ou -3, -1, 1ou 3. Portanto |x|/P <= 3/10 + 1/(10P). Equivalentemente |x| <= (3P + 1)/10.
Além disso, essa desigualdade é estrita em P=11, porque em P=11nós temos x=-1e k=-1. O menor Ppara o qual a igualdade é válida P=13(onde x=4e k=3).
Portanto, o maior que |x|/Pjá existe é 3/10 + 1/(10*13), porque P=13é o primeiro primo para o qual temos k=3e, entre aqueles com k=3, o 1/(10P)termo é maior quando Pmenor (ou seja, em P=13). Portanto, para todos P, também temos |x|/P <= 3/10 + 1/130 = 4/13 < 1/3. Isso explica por que, no código acima, podemos inicializar em i = P/3vez de precisar começar emP/2 .
Além disso, os limites na seção Utilidade acima agora podem ser aprimorados.
Lema : Deixe N = 10c + donde c > 0e 0 <= d <= 9. Entãoc + d|x| < N/10 + 9(3P + 1)/10 . (Observe a desigualdade estrita.)
Prova de lema: por casos. Caso I:, d = 0então N = 10c. Entãoc + d|x| = c = N/10 < N/10 + 9(3P + 1)/10 .
Caso II: 0 < d <= 9. Então 10c = N - d < Nsim c < N/10. Portantoc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10 . QED.
Assim, se N > 3P(e N = 10c + dcomo antes), então
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
Então, se N > 3Pentão c + d|x| < N.
Portanto, só temos de encontrar P, 2Pe 3P, juntamente com x. Dado N > 0, enquanto N > 3P, substituímos Npor |c + dx|, o que diminui N. Eventualmente nós chegaremos N <= 3P; Nesse ponto, parar e verificar se Né igual a qualquer um dos números 0, P, 2P, ou 3P.
Não podemos fazer melhor do que 3Pem geral. Por exemplo, suponha P = 13e N = 39, então x = 4. Em seguida, substituindo Npor dx + c = 9(4) + 3folhas Ninalteradas.
xvalor absoluto, onde10*x-1é divisível pela entrada.