Calcular la norma p-adic de un número racional
Escriba una función o un programa que tome 3 enteros m,n,p
(donde p
es un primo positivo) como entrada, que genere la norma p-adic (denotada por |m/n|_p
) como una fracción (completamente reducida). Se sabe que Fermat tiene márgenes muy pequeños, pero lo que se desconoce es que solo tenía una pantalla de computadora muy pequeña. ¡Intenta hacer el código lo más corto posible para que quepa en la pantalla de Fermat!
Definición
Dado un primo p
, cada fracción m/n
puede escribirse de manera única (ignorando los signos) como (a/b)* p^e
tal que e
sea un entero y p
no divida a
ni a ninguno b
. La norma p-adic de m/n
es p^-e
. Hay un caso especial, si la fracción es 0: |0|_p = 0
.
El formato de salida debe ser x/y
(p 1/3
. Ej ., Para enteros, se permite ambos 10
o de manera equivalente 10/1
, para números negativos debe haber un signo menos, p -1/3
. Ej. )
Detalles
El programa debe usar stdin / stdout, o simplemente consistir en una función que devuelva el número racional o cadena. Debe suponer que la entrada m/n
no se reduce por completo. Puedes suponer que p
es un primo. El programa tiene que poder procesar enteros entre -2^28
hasta 2^28
y no debe tomar más de 10 segundos.
No están permitidas las funciones integradas de factorización y verificación principal, así como la conversación básica incorporada y la función incorporada que calcula la valoración o norma p-adic.
Ejemplos (robados de wikipedia ):
x = m/n = 63/550 = 2^-1 * 3^2 * 5^-2 * 7 * 11^-1
|x|_2 = 2
|x|_3 = 1/9
|x|_5 = 25
|x|_7 = 1/7
|x|_11 = 11
|x|_13 = 1
Curiosidades interesantes
(No es necesario saber / leer para este desafío, pero tal vez sea bueno leerlo como motivación).
(Corríjame si uso las palabras incorrectas, o si algo está mal, no estoy acostumbrado a hablar de esto en inglés).
Si considera los números racionales como un campo, entonces la norma p-adic induce la métrica p-adic d_p(a,b) = |a-b|_p
. Luego puede completar este campo con respecto a esta métrica, lo que significa que puede construir un nuevo campo donde converjan todas las secuencias de cauchy, que es una buena propiedad topológica. (Lo cual, por ejemplo, los números racionales no tienen, pero los reales sí.) Estos números p-adic son, como habrás adivinado, usados mucho en la teoría de números.
Otro resultado interesante es el teorema de Ostrowski que básicamente dice que cualquier valor absoluto (como se define a continuación) en los números racionales es uno de los siguientes tres:
- Lo trivial:
|x|=0 iff x=0, |x|=1 otherwise
- El estándar (real):
|x| = x if x>=0, |x| = -x if x<0
- El p-adic (como lo definimos).
Un valor absoluto / una métrica es solo la generalización de lo que consideramos una distancia . Un valor absoluto |.|
satisface las siguientes condiciones:
|x| >= 0 and |x|=0 if x=0
|xy| = |x| |y|
|x+y| <= |x|+|y|
Tenga en cuenta que puede construir fácilmente métricas a partir de valores absolutos y viceversa: |x| := d(0,x)
o d(x,y) := |x-y|
, por lo tanto, son casi lo mismo si puede sumar / restar / multiplicar (es decir, en dominios integrales). Por supuesto, puede definir una métrica en conjuntos más generales, sin esta estructura.
PadicNorm
función de Mathematica también está fuera? : P|x|_11 = 11
, ¿verdad? ¿O está11
bien? ¿Y tiene que manejar elx=0
caso?x=0
caso y para este ejemplo se puede dar salida11
, así como11/1
, pero no tiene que imprimir|x|_11
.Respuestas:
Julia,
948075 bytesNota: el uso de avances de línea en lugar de punto y coma para facilitar la lectura, funcionará de cualquier manera.
Esto es bastante simple: la
g(m,n)
función utiliza la recursión y el resto (%
) para extraer elp^n
factor de la entradam
, con eln=1
valor predeterminado y luego multiplicado porp
cada paso de la recursión, de modo que la salida seráp^n
. El código aplica eso an/gcd(m,n)
, y luego am/gcd(m,n)
para obtener la expresión apropiada.k=gcd(m,n)
se usa para evitar calcular elgcd(m,n)
doble, para guardar caracteres.m!=0
es una prueba para manejar el caso dondex=0
.La salida es de la forma
N/1
o1/N
según corresponda, dondeN
estáp^e
.fuente
J,
3534 bytesEste es un verbo binario que toma el primo
p
como argumento izquierdo y la matrizm n
como argumento derecho. Siempre imprime la barra diagonal/
y devuelve0/1
sim = 0
. Úselo así:Explicación
Los
x:
giros en precisión extendida, ya que estamos manejando números muy grandes. El resto del código funciona de la siguiente manera:fuente
CJam, 42 bytes
Esto termina con un error (después de imprimir 0) para la entrada 0. Pruébelo en línea en el intérprete de CJam .
fuente
Stax , 32 bytes
Ejecutar y depurarlo
Debería poder hacerlo más corto. El soporte nativo para la fracción de Stax es bastante bueno.
ASCII equivalente:
fuente