Dado un primo P
mayor que 10
, su programa o función debe calcular su regla de divisibilidad x
, definida como el número entero con el valor absoluto más pequeño que produce un múltiplo del primo original cuando se multiplica por el último dígito del primo y se agrega al resto del original. principal.
Ejemplo
Dada una entrada 31
, el último dígito es 1
y el resto del número es 3
. Por lo tanto, su programa debe encontrar el número entero x
con un valor absoluto mínimo tal que 1*x + 3
sea un múltiplo de 31
. En este caso, x=-3
funciona, por lo que el programa o función volvería -3
.
Dada una entrada 1000003
, el último dígito es 3
y el resto del número es 100000
. Por lo tanto su programa encontraría x=300001
ya 3*300001+100000 = 1000003
que es un múltiplo de 1000003
.
Antecedentes matemáticos
El valor de x
se puede usar como prueba de divisibilidad. Si un número N
es divisible por P
, entonces al sumar x
veces el último dígito de N
al resto de, se N
obtendrá un múltiplo de P
if y only if N
es divisible por P
en primer lugar.
Para P=11
, obtenemos x=-1
, que es equivalente a la conocida regla de divisibilidad para 11
: un número es divisible por 11
la diferencia alterna de sus dígitos es divisible por 11
.
Reglas
- La salida puede tener cualquier forma que codifique claramente tanto el signo como el valor de la salida.
- El primo de entrada estará entre 10 y 2 ^ 30.
- No necesita manejar si la entrada no es un primo o no está en el rango.
- No es necesario que si ambos mango
x
y-x
son salidas válidas (no debería suceder). - Se permite la fuerza bruta, pero se aprecian soluciones más creativas.
- Este es el código de golf , por lo que gana el código más corto en cada idioma . No permita que las respuestas en los idiomas de golf lo desalienten a publicar en otros idiomas.
Casos de prueba
Input Output
11 -1
13 4
17 -5
19 2
23 7
29 3
31 -3
37 -11
41 -4
43 13
47 -14
53 16
59 6
61 -6
67 -20
71 -7
73 22
79 8
83 25
89 9
97 -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999
fuente
x
valor absoluto más pequeño donde10*x-1
sea divisible por la entrada.(3 / (n % 5 * 2 - 5) * n + 1) / 10
y(n % 5 * 2 - 5^2) * n / 10 + 1
puede encontrar un valor absoluto mínimo para algo como esto? Mi primera intuición habría sido calcular el mínimo común múltiplo utilizando el máximo común divisor calculado con el algoritmo de Euclides.x
, agregarlo y aún así obtener un número divisible porn
. Si luego multiplicamos el nuevo número por 10 y restamos el número original, sigue siendo divisible porn
. El comentario de xnor se desprende de un poco de álgebra. El siguiente paso es reorganizar la fórmula de modo que déx
en términos den
: x =(k*n+1)/10
. Queremos que el más pequeño absolutax
por lo que, por lo tanto queremos que el más pequeño absolutak
, y esto debe ser lo que uno de-3
,-1
,1
o3
(dependiendo den
'último dígito s) que hace que la división exacta.Respuestas:
JavaScript (ES6),
322523 bytes3/(n%5*2-5)
se escribiría9/n(mod -10)
si tuviera acceso a una división de módulo equilibrada. Editar: Guardado 2 bytes gracias a @EgorSkriptunofffuente
n=>((n%10*2%14-3)*n+1)/10
conn=>(3/(n%5*2-5)*n+1)/10
Python 2 , 27 bytes
Pruébalo en línea!
Las operaciones se realizan izquierda a derecha:
(((n%5)*2)-5)^2
.Utilicé mi fuerza bruta aritmética para encontrar la expresión
n%5*2-5^2
a realizar{1:-1,3:3,2:-3,4:1}[k]
, tomando el inverso negativo de un mod de residuo 5 en el rango[-2..2]
.fuente
3/(n%5*2-5)
tiene la misma longitud que(n%5*2-5^2)
)n%5*2-6^3
. Aunque solo busqué la longitud de la expresión sin parens, mientras que3/(n%5*2-5)
es dos caracteres más larga, pero se guarda en parens externos debido a la precedencia. La búsqueda de expresiones de esta longitud debería llevar un tiempo. Este caso de uso sugiere una opción para encontrar solo expresiones que se puedan usar en un contexto dado a través de su operación más externa que tenga suficiente precedencia.jalea ,
108 bytesPruébalo en línea!
Explicaciones
fuente
Brachylog , 14 bytes
Pruébalo en línea!
fuente
Python 2 ,
695453 bytesEditar: -15 bytes gracias a @ Mr.Xcoder
Editar: -1 byte usando recursividad
Pruébalo en línea!
fuente
Python 2 ,
31 2927 bytesPruébalo en línea!
fuente
Japt ,
169 bytesSe guardaron demasiados bytes gracias a una observación de @xnor
¡Pruébalo en línea! Puede tomar un par de segundos en entradas más grandes.
Explicación
fuente
Java 8,
2321 bytesPuerto de la respuesta JavaScrip (ES6) de @Neil , pero -2 bytes gracias a @Nevay debido a un piso implícito de enteros.
Pruébalo aquí
fuente
n->3/(n%5*2-5)*++n/10
Pyke , 12 bytes
Pruébalo aquí!
fuente
Pyth , 14 bytes
Pruébalo aquí
fuente
Python 2 ,
4443 bytes(Tachado 44 sigue siendo 44.) ¡ Gracias a Fireflame241 por guardar un byte!
Pruébalo en línea!
Hay exactamente un número entre
0
yP-1
que es un inverso de10
. Pero si ese inversou
es mayor queP/2
, entonces(u-P)
también es inverso y tiene un valor absoluto menor queu
. Resulta que realmente estamos buscando el número únicox
entre-P/2
yP/2
que es un inverso de10
.El código anterior hace exactamente eso, comenzando en (el piso de)
P/2
y bajando hasta alcanzar un inverso. Esto debe suceder para un número mayor que-P/2
mientrasP
sea un primo mayor que10
. Más precisamente, terminará si y solo siP
es coprime para10
.Editar: en realidad resulta que
x
está garantizado entre-P/3
yP/3
, por lo que la versión actual comienza enP/3
y baja desde allí. Ver la sección etiquetada Mejorado vinculado para obtener una explicación de esto.Explicación matemática
No fue inmediatamente obvio para mí por qué funcionó la prueba de divisibilidad. Aquí hay una explicación, en caso de que alguien más se preguntara.
Sea
P
un primo, mayor que10
, cuyo último dígito esb
. AsíP = 10a + b
donde
a > 0
y0 <= b < 10
. De hechob
es o bien1
,3
,7
, o9
, a causa de una mayor prime10
final necesidad en uno de estos dígitos.Ahora supongamos
bx + a = 0 (mod P)
. Luegoa = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Como
P
es primo, los enterosmod P
son un dominio integral . Entoncesb = 0 (mod P)
, o1 - 10x = 0 (mod P)
.Sabemos
0 <= b < 10 < P
, por lo que sib = 0 (mod P)
a continuaciónb = 0
. Pero dijimosb
está bien1
,3
,7
, o9
, por lo que esto es imposible. Por1 - 10x = 0 (mod P)
lo tanto , entonces10x = 1 (mod P)
. En otras palabras,x
es el inverso de10
, móduloP
.Ahora suponga que
N
es un entero no negativo cuyo último dígito esd
, porN = 10c + d.
lo que tenemos una cadena de declaraciones equivalentes:10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED
¿Utilidad?
También me preguntaba si la prueba de divisibilidad (dada
N = 10c + d
, reemplazadaN
pordx + c
) sería realmente productiva en la práctica. O al menos, ¿se reemplaza confiablementeN
por un número menor queN
(en valor absoluto)?Supongamos
N = 10c + d
, dondec >= 0
y0 <= d < 10
. Por lo tanto10c = N - d <= N
. Por la desigualdad del triángulo,|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Entonces si
5P <= 9N/10
, entonces|c + dx| < N
.En particular, si
N >= 6P
, entonces|c + dx| < N
. Por lo tanto, dadoP
que comenzamos calculando2P
,3P
, ...,6P
, junto conx
. Entonces dadoN
, corremos el test de la divisibilidad en repetidas ocasiones hasta llegar a un número menor o igual a6P
, y comprobar si el resultado es cualquiera de los números0
,P
,2P
, ...,6P
.(Por supuesto, cada vez que alcanzamos un número negativo, lo reemplazamos por su valor absoluto, lo cual está bien ya que
q
es divisible porP
si y solo si lo(-q)
es).Límite mejorado
Me di cuenta de que
|x|/P
nunca parecía estar cerca1/2
. De hecho, parecía que siempre era menor que1/3
... o, al examinarlo más de cerca, siempre estaba muy cerca de uno1/10
u otro3/10
. El más grande que haya tenido parece ser4/13
(lo que sucede cuandoP=13
yx=4
). ¿Por qué sería esto?Deje
u
ser un número entero y suponga que10u = kP + 1
para algún número enterok
, también lou
es un10
módulo inversoP
. Entonces también sabemos quek
es relativamente primo10
, ya quek(-P)
es equivalente al1
módulo10
.Ahora, sabemos que todas las inversas del
10
móduloP
difieren en múltiplos deP
, por lo que podemos tomar el número enterou
y sumar o restar múltiplosP
a voluntad, y el resultado siempre será un inverso del10
móduloP
. Supongamos que elegimos restarP
deu
: obtenemos10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
En otras palabras, la disminución (respectivamente, aumentando)
u
porP
corresponde a la disminución (en aumento)k
por10
. Queremos añadir / restar múltiplos deP
partiru
hasta que el lado izquierdo se reduce al mínimo en valor absoluto; pero el lado izquierdo se minimiza exactamente cuando se minimiza el lado derecho, y así queremos añadir / restar10
dek
hasta que el lado derecho se reduce al mínimo en valor absoluto.Pero sabemos que esto sucederá cuando
k
está entre-5
y5
, y por lo tanto (ya quek
es relativamente primos a10
) este mediok
es o bien-3
,-1
,1
, o3
. (Este es el contenido del comentario de @ Neil bajo el OP. ¡ Gracias, Neil! )Así, cuando
|u|
se reduce al mínimo (es decir,u=x
), tendremosx/P = u/P = k/10 + 1/(10P)
, dondek
es o bien-3
,-1
,1
, o3
. Por lo tanto|x|/P <= 3/10 + 1/(10P)
. De manera equivalente,|x| <= (3P + 1)/10
.Además, esta desigualdad es estricta en
P=11
, porque enP=11
tenemosx=-1
yk=-1
. El más pequeñoP
para el que se cumple la igualdad esP=13
(dóndex=4
yk=3
).Por lo tanto, el más grande que
|x|/P
se obtiene es3/10 + 1/(10*13)
, porqueP=13
es el primer primo para el que tenemosk=3
, y entre aquellos conk=3
, el1/(10P)
término es más grande cuandoP
es más pequeño (es decir, enP=13
). Por lo tanto, para todosP
, también tenemos|x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. Esto explica por qué en el código anterior podemos inicializar eni = P/3
lugar de tener que comenzar enP/2
.Además, los límites en la utilidad sección de anterior ahora se pueden mejorar.
Lema : Dejar
N = 10c + d
dóndec > 0
y0 <= d <= 9
. Luegoc + d|x| < N/10 + 9(3P + 1)/10
. (Tenga en cuenta la estricta desigualdad).Prueba de Lemma: por casos. Caso I:
d = 0
entoncesN = 10c
. Luegoc + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.Caso II:
0 < d <= 9
. Entonces10c = N - d < N
, entoncesc < N/10
. Por lo tantoc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QEDPor lo tanto, si
N > 3P
(yN = 10c + d
como antes), entonces3P + 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
Entonces, si
N > 3P
entoncesc + d|x| < N
.Por lo tanto, solo tenemos que encontrar
P
,2P
y3P
, junto conx
. DadoN > 0
, mientrasN > 3P
, reemplazamosN
por|c + dx|
, lo que disminuyeN
. Finalmente lo conseguiremosN <= 3P
; en ese punto nos detenemos y comprobar siN
es igual a cualquiera de los números0
,P
,2P
, o3P
.No podemos hacerlo mejor que
3P
en general. Por ejemplo, supongamosP = 13
yN = 39
, entoncesx = 4
. Luego reemplazandoN
pordx + c = 9(4) + 3
hojasN
sin cambios.fuente
-1
fuera del paréntesis: 43 bytesEspacio en blanco , 92 bytes
Tenga en cuenta que la sintaxis de este lenguaje consiste solo en espacios en blanco , por lo que cada carácter de espacio en blanco se ha prefijado aquí con S, T o L (correspondiente a Espacio, Tabulación y Salto de línea, respectivamente). Estos se pueden eliminar sin perder la funcionalidad, pero se incluyen aquí para mostrarlos correctamente.
Pruébalo en línea!
fuente
Japt , 14 bytes
Inspirado en la solución de Neil .
¡Pruébelo en línea!
Explicación:
fuente
Pyke , 10 bytes
Pruébalo aquí!
fuente
Excel, 27 bytes
Podría ingresarse en la celda como
para 25 bytes, pero Excel se actualiza automáticamente.
fuente