Liens pertinents ici et ici , mais voici la version courte:
Vous avez une entrée de deux entiers a
et b
entre l'infini négatif et l'infini (bien que si nécessaire, je peux restreindre la plage, mais la fonction doit toujours accepter les entrées négatives).
Définition du symbole Kronecker
Vous devez renvoyer le symbole Kronecker (a|b)
pour les entrées a
et b
où
(a|b) = (a|p_1)^e_1 * (a|p_2)^e_2 * ... * (a|p_n)^e_n
où b = p_1^e_1 * p_2^e_2 * ... * p_n^e_n
, et p_i
et e_i
sont les nombres premiers et exposants dans la décomposition en facteurs premiers de b
.
Pour un nombre impair p
, (a|p)=a^((p-1)/2) (mod p)
tel que défini ici .
Pour b == 2
,(n|2)={0 for n even; 1 for n odd, n=+/-1 (mod 8); -1 for n odd, n=+/-3 (mod 8)
Pour b == -1
,(n|-1)={-1 for n<0; 1 for n>0
Si a >= b
, (a|b) == (z|b)
où z == a % b
. Par cette propriété, et comme expliqué ici et ici , a
est un résidu quadratique de b
si z
est, même si a >= b
.
(-1|b)
= 1
si b == 0,1,2 (mod 4)
et -1
si b == 3 (mod 4)
. (0|b)
est , 0
sauf pour ce (0|1)
qui est 1
, parce (a|1)
est toujours 1
et négative a
, (-a|b) == (-1|b) * (a|b)
.
La sortie du symbole Kronecker est toujours -1, 0 or 1
, où la sortie est 0
si a
et b
ont des facteurs communs. Si b
est un premier impair, (a|b) == 1
si a
est un mod de résidu quadratiqueb
, et -1
si ce n'est pas un résidu quadratique.
Règles
Votre code doit être un programme ou une fonction.
Les entrées doivent être dans l'ordre
a b
.La sortie doit être soit
-1
,0
soit1
.Il s'agit de code golf, donc votre code n'a pas besoin d'être efficace, juste court.
Aucune fonction intégrée qui calcule directement le Kronecker ou les symboles Jacobi et Legendre associés. Les autres fonctions intégrées (pour la factorisation principale, par exemple) sont équitables.
Exemples
>>> kronecker(1, 5)
1
>>> kronecker(3, 8)
-1
>>> kronecker(15, 22)
1
>>> kronecker(21, 7)
0
>>> kronecker(5, 31)
1
>>> kronecker(31, 5)
1
>>> kronecker(7, 19)
1
>>> kronecker(19, 7)
-1
>>> kronecker(323, 455625)
1
>>> kronecker(0, 12)
0
>>> kronecker(0, 1)
1
>>> kronecker(12, 0)
0
>>> kronecker(1, 0)
1
>>> kronecker(-1, 5)
1
>>> kronecker(1, -5)
1
>>> kronecker(-1, -5)
-1
>>> kronecker(6, 7)
-1
>>> kronecker(-1, -7)
1
>>> kronecker(-6, -7)
-1
C'est une fonction compliquée, alors faites-moi savoir si quelque chose n'est pas clair.
la source
Réponses:
CJam (70 octets)
Démo en ligne (cas de test générés avec Mathematica).
Dissection
J'ai trouvé plusieurs façons d'évaluer
(a|2)
le même nombre de caractères, et j'ai choisi d'utiliser celui avec la présentation la plus claire.integer array <W=
est IMO une façon assez élégante de faire des replis: si l'entier est supérieur à la longueur du tableau, nous sélectionnons le dernier élément.Autres commentaires
Il est décevant que pour le premier impair,
p
le style direct de Fermat(a|p)
soit si court, car il y a une façon très golfique de trouver(a|n)
un impair positifn
que je voulais utiliser. La base est le lemme de Zolotarev:Cela a été renforcé par Frobenius pour
et par Lerch à
Voir Brunyate et Clark, Extending the Zolotarev-Frobenius approach to quadratic reciprocity , The Ramanujan Journal 37.1 (2014): 25-50 pour les références.
Et il peut facilement être renforcé un peu plus loin (même si je n'ai pas vu cela dans la littérature) pour
Preuve: si
a
est coprime àb
alors on utilise Zolotarev-Frobenius-Lerch; sinon, la carte n'est pas une permutation et le symbole Levi-Civita est0
comme souhaité.Cela donne le calcul du symbole Jacobi
Mais le traitement spécial requis
(a|-1)
et(a|2)
signifie que je n'ai pas trouvé de moyen de calculer le symbole Kronecker qui est plus court avec cette approche: il est plus court de factoriser et de traiter les nombres premiers individuellement.la source
Python 3,
747369335 octetsÀ titre d'exemple de réponse, seulement légèrement joué au golf, et pour vous donner une idée de ce à quoi ressemblera une réponse.
Et oui, la factorisation principale et les bits d'encodage de la longueur d'exécution sont importés de Pyth avec des excuses à isaacg .
la source
Mathematica,
169175165 octetsla source
LabVIEW, 44 octets Primitives LabVIEW
Puisque son i symétrique a échangé les entrées si a était plus grand que b.Représente la vraie formule maintenant
compter comme toujours selon
pour vrai cas
la source
(a|b) != (b|a)
dans tous les cas. Dans la plupart des cas, oui, mais pas dans tous. Bien que cela fonctionnerait si vous réduisieza mod b
au lieu de les échanger.Julia, 195 octets
Il s'agit d'une fonction récursive
k
qui accepte deux entiers et renvoie un entier.Non golfé:
la source
Haskell, 286 octets
Probablement pas complètement optimisé, mais un vaillant effort. Le symbole Kronecker est défini comme la fonction infixe a # b, c'est-à-dire
la source