Calculer la norme p-adique d'un nombre rationnel
Écrivez une fonction ou un programme, qui prend en entrée 3 entiers m,n,p
(où p
est un nombre positif), qui produit la norme p-adique (notée par |m/n|_p
) comme une fraction (complètement réduite). Fermat est connu pour n'avoir que de très petites marges, mais ce qui est plutôt inconnu, c'est qu'il n'avait qu'un très petit écran d'ordinateur. Essayez donc de rendre le code aussi court que possible pour qu'il tienne sur l'écran de Fermat!
Définition
Étant donné un nombre premier p
, chaque fraction m/n
peut être écrite de manière unique (en ignorant les signes) comme (a/b)* p^e
telle qui e
est un entier et p
ne divise ni a
ni b
. La norme p-adique de m/n
est p^-e
. Il y a un cas particulier, si la fraction est 0: |0|_p = 0
.
Le format de sortie doit être x/y
(par exemple 1/3
; pour les entiers les deux 10
ou de manière équivalente 10/1
est autorisé, pour les nombres négatifs, il doit y avoir un moins négatif, par exemple -1/3
)
Détails
Le programme doit utiliser stdin / stdout, ou simplement se composer d'une fonction qui renvoie le nombre rationnel ou la chaîne. Vous devez supposer que l'entrée m/n
n'est pas complètement réduite. Vous pouvez supposer que p
c'est une prime. Le programme doit être capable de traiter des nombres entiers -2^28
allant jusqu'à 2^28
, et ne devrait pas prendre plus de 10 secondes.
Les fonctionnalités intégrées de factorisation et de vérification principale ne sont pas autorisées, ainsi que la conversion de base intégrée et la fonction intégrée qui calcule la valeur ou la norme p-adique.
Exemples (volés sur 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
Anecdotes intéressantes
(Pas nécessaire de savoir / lire pour ce défi, mais peut-être agréable à lire comme motivation.)
(Veuillez me corriger si j'utilise les mauvais mots, ou si quelque chose d'autre ne va pas, je n'ai pas l'habitude d'en parler en anglais.)
Si vous considérez les nombres rationnels comme un champ, la norme p-adique induit la métrique p-adique d_p(a,b) = |a-b|_p
. Ensuite, vous pouvez compléter ce champ en ce qui concerne cette métrique, cela signifie que vous pouvez construire un nouveau champ où toutes les séquences de cauchy convergent, ce qui est une belle propriété topologique. (Ce qui, par exemple, les nombres rationnels n'ont pas, mais les réels en ont.) Ces nombres p-adiques sont, comme vous l'avez peut-être deviné, beaucoup utilisés dans la théorie des nombres.
Un autre résultat intéressant est le théorème d'Ostrowski qui dit essentiellement que toute valeur absolue (telle que définie ci-dessous) sur les nombres rationnels est l'une des trois suivantes:
- Le trivial:
|x|=0 iff x=0, |x|=1 otherwise
- La norme (réelle):
|x| = x if x>=0, |x| = -x if x<0
- Le p-adique (tel que nous l'avons défini).
Une valeur absolue / une métrique n'est que la généralisation de ce que nous considérons comme une distance . Une valeur absolue |.|
satisfait aux conditions suivantes:
|x| >= 0 and |x|=0 if x=0
|xy| = |x| |y|
|x+y| <= |x|+|y|
Notez que vous pouvez facilement construire des métriques à partir de valeurs absolues et vice versa: |x| := d(0,x)
ou d(x,y) := |x-y|
alors elles sont presque les mêmes si vous pouvez ajouter / soustraire / multiplier (c'est-à-dire dans des domaines intégraux). Vous pouvez bien sûr définir une métrique sur des ensembles plus généraux, sans cette structure.
PadicNorm
fonction de Mathematica est également désactivée? : P|x|_11 = 11
, non? Ou est-ce11
bien? Et faut-il gérer l'x=0
affaire?x=0
cas et pour cet exemple, vous pouvez11
également11/1
imprimer, mais vous n'avez pas besoin d'imprimer|x|_11
.Réponses:
Julia,
948075 octetsRemarque: l'utilisation de sauts de ligne à la place des points-virgules pour plus de lisibilité - fonctionnera de la même façon.
C'est assez simple - la
g(m,n)
fonction utilise la récursivité et reste (%
) pour extraire lep^n
facteur d'entréem
, avecn=1
par défaut et ensuite multiplié parp
à chaque étape de la récursivité, de sorte que la sortie serap^n
. Le code applique cela àn/gcd(m,n)
, puis àm/gcd(m,n)
pour obtenir l'expression appropriée.k=gcd(m,n)
est utilisé pour éviter de calculer legcd(m,n)
double, pour enregistrer les caractères.m!=0
est un test pour gérer le cas oùx=0
.La sortie est de la forme
N/1
ou,1/N
le cas échéant, oùN
estp^e
.la source
J,
3534 octetsIl s'agit d'un verbe binaire qui prend le premier
p
comme argument de gauche et le tableaum n
comme argument de droite. Il imprime toujours la barre oblique/
et renvoie0/1
ifm = 0
. Utilisez-le comme ceci:Explication
Les
x:
tours sur la précision étendue, car nous traitons de très grands nombres. Le reste du code fonctionne comme suit:la source
CJam, 42 octets
Cela se termine par une erreur (après l'impression de 0) pour l'entrée 0. Essayez-le en ligne dans l' interpréteur CJam .
la source
Stax , 32 octets
Exécuter et déboguer
Doit pouvoir le raccourcir. Le support natif de fraction par Stax est assez soigné.
Équivalent ASCII:
la source