Calcular la norma p-adic de un número racional

11

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 pes 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/npuede escribirse de manera única (ignorando los signos) como (a/b)* p^etal que esea ​​un entero y pno divida ani a ninguno b. La norma p-adic de m/nes 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 10o 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/nno se reduce por completo. Puedes suponer que pes un primo. El programa tiene que poder procesar enteros entre -2^28hasta 2^28y 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.

falla
fuente
¿Asumo que la PadicNormfunción de Mathematica también está fuera? : P
Alex A.
Asumes correcto / ly. (que se emplea aquí?)
flawr
A menos que la sección de Propiedades interesantes sea útil para completar el desafío, diría que es mejor simplemente vincular esa información para las partes interesadas. De lo contrario, desordena innecesariamente la publicación.
Alex A.
Para ser claros, la salida debería ser algo así |x|_11 = 11, ¿verdad? ¿O está 11bien? ¿Y tiene que manejar el x=0caso?
Glen O
@GlenO correcta, se tiene que manejar el x=0caso y para este ejemplo se puede dar salida 11, así como 11/1, pero no tiene que imprimir |x|_11.
falla

Respuestas:

3

Julia, 94 80 75 bytes

f(m,n,p)=(k=gcd(m,n)
g(m)=m%p>0?g(m÷p)p:1
m!=0?print(g(n÷k),/,g(m÷k)):0)

Nota: 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 el p^nfactor de la entrada m, con el n=1valor predeterminado y luego multiplicado por pcada paso de la recursión, de modo que la salida será p^n. El código aplica eso a n/gcd(m,n), y luego a m/gcd(m,n)para obtener la expresión apropiada. k=gcd(m,n)se usa para evitar calcular el gcd(m,n)doble, para guardar caracteres. m!=0es una prueba para manejar el caso donde x=0.

La salida es de la forma N/1o 1/Nsegún corresponda, donde Nestá p^e.

Glen O
fuente
1

J, 35 34 bytes

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:

Este es un verbo binario que toma el primo pcomo argumento izquierdo y la matriz m ncomo argumento derecho. Siempre imprime la barra diagonal /y devuelve 0/1si m = 0. Úselo así:

  f =: (,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:
  5 f 63 550
25/1

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:

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])
                        ^         Power: this gives the array p^n p^m
                         +.       Take element-wise GCD with
                           |.@]   the rotated array n m; this gives
                                  the largest powers of p that divide n and m
                      <.          Take element-wise minimum with
                     [            The array m n to handle the m=0 case correctly
              %+./                Divide this array by its GCD to get it to lowest terms
        &":/                      Convert both elements to strings
 ,'/'&,                           Insert the slash '/' between them
Zgarb
fuente
0

CJam, 42 bytes

q~)\_:*g_sW<o@*28#f{{{_@\%}h;}:G~}_~Gf/'/*

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 .

Dennis
fuente
0

Stax , 32 bytes

éE▌ΦΔΘao£╙)ΩuÅI~AAε3∞xC█&½╤%╩▌ïö

Ejecutar y depurarlo

Debería poder hacerlo más corto. El soporte nativo para la fracción de Stax es bastante bueno.

ASCII equivalente:

hY{y:+y|aEGsG-ys|**}0?}0{^scxHY%Cy/sWd
Weijun Zhou
fuente