Une formule pour les congruences

10

Le théorème du reste chinois peut être très utile en arithmétique modulaire.

Par exemple, considérons l'ensemble de relations de congruence suivant:

Ensemble de congruence

Pour des ensembles de relations de congruence comme celui-ci, où toutes les bases ( 3, 5, 7dans cet exemple) sont co-amorcées les unes avec les autres, il y aura un et un seul entier nentre 1et le produit des bases ( 3*5*7 = 105dans cet exemple) inclusif qui satisfait les relations .

Dans cet exemple, le nombre serait 14généré par cette formule:

formule

2, 4, and 0sont donnés à partir de l'exemple ci-dessus.

70, 21, 15sont les coefficients de la formule et ils dépendent des bases, 3, 5, 7.

Pour calculer les coefficients de la formule ( 70, 21, 15dans notre exemple) pour un ensemble de bases, nous utilisons la procédure suivante.

Pour chaque numéro adans un ensemble de bases:

  1. Trouvez le produit de toutes les autres bases, noté P.
  2. Trouvez le premier multiple Pqui laisse un reste 1lorsqu'il est divisé par a. C'est le coefficient de a.

Par exemple, pour calculer le coefficient qui correspond à la base 3, nous trouvons le produit de toutes les autres bases (c.-à-d. 5*7 = 35), Puis trouvons le premier multiple de ce produit qui laisse un reste 1lorsqu'il est divisé par la base.

Dans ce cas, 35laisse un reste 2lorsqu'il est divisé par 3, mais 35*2 = 70laisse un reste 1lorsqu'il est divisé par 3, tout 70comme le coefficient correspondant pour 3. De même, 3*7 = 21laisse un reste 1lorsqu'il est divisé par 5et 3*5 = 15laisse un reste 1lorsqu'il est divisé par 7.

En un mot

Pour chaque numéro ad'un ensemble de chiffres:

  1. Trouvez le produit de tous les autres nombres, notés P.
  2. Trouvez le premier multiple Pqui laisse un reste 1lorsqu'il est divisé par a. C'est le coefficient de a.

Le défi

  • Le défi est, pour un ensemble de deux bases ou plus, de trouver l'ensemble des coefficients correspondants.
  • L'ensemble de bases est garanti pour être co-amorcé par paire et chaque base est garantie d'être supérieure à 1.
  • Votre entrée est une liste d'entiers sous forme d'entrée [3,4,5]ou de chaîne séparée par des espaces "3 4 5"ou comment vos entrées fonctionnent.
  • Votre sortie doit être soit une liste d'entiers, soit une chaîne séparée par des espaces qui indique l'ensemble de coefficients.

Cas de test

input             output
[3,5,7]           [70,21,15]
[2,3,5]           [15,10,6]
[3,4,5]           [40,45,36]
[3,4]             [4,9]
[2,3,5,7]         [105,70,126,120]
[40,27,11]        [9801,7480,6480]
[100,27,31]       [61101,49600,56700]
[16,27,25,49,11]  [363825,2371600,2794176,5583600,529200]

Un grand merci à Leaky Nun pour son aide dans la rédaction de ce défi. Comme toujours, si le problème n'est pas clair, faites-le moi savoir. Bonne chance et bon golf!

Sherlock9
la source
Y aura-t-il toujours 3 chiffres dans l'entrée?
xnor
@xnor Nope. Cas de test modifiés.
Sherlock9

Réponses:

5

Haskell, 61 55 53 octets

f x=[[p|p<-[0,product x`div`n..],p`mod`n==1]!!0|n<-x]

Définit une fonction fqui prend une entrée et donne une sortie sous forme de liste d'entiers.

f x=[                                          |n<-x]  (1)
              product x                                (2)
                       `div`n                          (3)

D'abord, nous bouclons sur tous les entiers dans l'entrée (1). Ensuite, nous prenons le produit de tous les entiers (2) et divisons par n pour obtenir uniquement le produit des non- nentiers, qui est P(3).

           [0,               ..]                       (4)
     [p|p<-                     ,p`mod`n==1]           (5)
                                            !!0        (6)

Ensuite, nous utilisons le résultat ( P) comme valeur de pas pour une plage commençant à zéro (4). Nous prenons le résultat, [0, P, 2P, 3P, ...]et le filtrons sur des valeurs pour lesquelles le résultat d'une opération mod-n est un (5). Enfin, nous prenons le premier élément, qui fonctionne grâce à l'évaluation paresseuse (6).

Merci à @xnor pour 2 octets!

Poignée de porte
la source
1
Bienvenue chez haskell! Je pense que vous quotpouvez être divet headpouvez l'être !!0.
xnor
4

Gelée , 11 7 octets

P:*ÆṪ%P

Essayez-le en ligne! ou vérifiez tous les cas de test .

Contexte

Soit P et a des entiers premiers strictement positifs .

Le processus en deux étapes de la question - trouver un multiple de P qui laisse un reste de 1 lorsqu'il est divisé par a - peut être décrit par l'équation de congruence suivante.

équation de congruence linéaire

Par le théorème d'Euler-Fermat , nous avons

Théorème d'Euler-Fermat

φ désigne la fonction de totient d'Euler . De ce résultat, nous déduisons ce qui suit.

formule pour l'équation de congruence linéaire

Enfin, comme le défi nous oblige à calculer Px , nous observons que

formule pour le résultat final

Pa peut être calculé comme le produit de tous les modules.

Comment ça fonctionne

P:*ÆṪ%P  Main link. Argument: A (list of moduli)

P        Yield the product of all moduli.
 :       Divide the product by each modulus in A.
   ÆṪ    Apply Euler's totient function to each modulus.
  *      Raise each quotient to the totient of its denominator.
     %P  Compute the remainder of the powers and the product of all moduli.
Dennis
la source
2

J, 13 octets

*/|5&p:^~*/%]

Basé sur la réponse étonnante de @Dennis .

Usage

Certains cas de test auront besoin de l'entrée sous forme d'entiers étendus qui ont un suffixe x.

   f =: */|5&p:^~*/%]
   f 3 5 7
70 21 15
   f 40x 27 11
9801 7480 6480
   f 16x 27 25 49 11
363825 2371600 2794176 5583600 529200

Explication

*/|5&p:^~*/%]  Input: list B
         */    Reduce B using multiplication to get the product of the values
            ]  Identity function, get B
           %   Divide the product by each value in B, call the result M
   5&p:        Apply the totient function to each value in B, call the result P
       ^~      Raise each value in M to the power of its corresponding value in P
*/             The product of the values in B
  |            Compute each power modulo the product and return

Essayez-le ici.

miles
la source
2

Mathematica, 27 octets

PowerMod[a=LCM@@#/#,-1,#]a&
alephalpha
la source
1

Gelée, 14 13 octets

P:×"Ḷð%"’¬æ.ḷ

Un octet enregistré grâce à @ Dennis !

Utilise le processus décrit dans la spécification de défi. L'entrée est une liste de bases et la sortie est une liste de coefficients.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication

P:×"Ḷð%"’¬æ.ḷ  Input: a list B
P              Get the product of the list
 :             Divide it by each value in the B, call it M
    Ḷ          Get a range from 0 to k for k in B
  ×"           Vectorized multiply, find the multiples of each M
     ð         Start a new dyadic chain. Input: multiples of M and B
      %"       Vectorized modulo, find the remainders of each multiple by B
        ’      Decrement every value
               If the remainder was 1, decrementing would make it 0
         ¬     Logical NOT, zeros become one and everything else becomes 0
            ḷ  Get the multiples of M
          æ.   Find the dot product between the modified remainders and the multiples
               Return
miles
la source
1

JavaScript (ES6), 80 octets

a.map(e=>[...Array(e).keys()].find(i=>p*i/e%e==1)*p/e,p=a.reduce((i,j)=>i*j))

J'ai essayé l'algorithme euclidien étendu mais cela prend 98 octets:

a=>a.map(e=>(r(e,p/e)+e)%e*p/e,p=a.reduce((i,j)=>i*j),r=(a,b,o=0,l=1)=>b?r(b,a%b,t,o-l*(a/b|0)):o)

Si les valeurs sont toutes premières, ES7 peut le faire en 56 octets:

a=>a.map(e=>(p/e%e)**(e-2)%e*p/e,p=a.reduce((i,j)=>i*j))
Neil
la source
1

Python + SymPy, 71 octets

from sympy import*
lambda x:[(prod(x)/n)**totient(n)%prod(x)for n in x]

Cela utilise l'algorithme de ma réponse Jelly . Les E / S se présentent sous la forme de listes de numéros SymPy.

Dennis
la source
1

Python 2, 87 84 octets

Une implémentation simple de l'algorithme. Suggestions de golf bienvenues.

a=input();p=1
for i in a:p*=i
print[p/i*j for i in a for j in range(i)if p/i*j%i==1]
Sherlock9
la source
Un programme complet économiserait 3 octets.
Dennis
1

Cheddar , 64 octets

n->n.map(i->(|>i).map(j->(k->k%i>1?0:k)(n.reduce((*))/i*j)).sum)
Leaky Nun
la source
Je devrais ajouter un .productqui fait .reduce((*))pour les tableaux ...
Downgoat
0

GAP , 51 octets

GAP a une fonction qui peut calculer l'exemple de motivation avec ChineseRem([2,5,7],[2,4,0]), mais cela ne facilite toujours pas l'obtention des coefficients. Nous pouvons obtenir le nième coefficient en utilisant la liste avec un à la nième position et des zéros aux autres positions comme deuxième argument. Nous devons donc créer ces listes et appliquer la fonction à toutes:

l->List(Basis(Integers^Size(l)),b->ChineseRem(l,b))
Christian Sievers
la source
0

Lot, 148 octets

@set p=%*
@set/ap=%p: =*%
@for %%e in (%*)do @for /l %%i in (1,1,%%e)do @call:l %%e %%i
@exit/b
:l
@set/an=p/%1*%2,r=n%%%1
@if %r%==1 echo %n%
Neil
la source
0

En fait, 14 octets

Cela utilise l'algorithme de la réponse Jelly de Dennis . Une autre réponse basée sur ma réponse Python est à venir. Suggestions de golf bienvenues. Essayez-le en ligne!

;π;)♀\;♂▒@♀ⁿ♀%

Comment ça fonctionne

                 Implicit input a.
;                Duplicate a.
 π;)             Take product() of a, duplicate and rotate to bottom.
    ♀\           Integer divide the product by each element of a. Call this list b.
      ;♂▒        Take that list, duplicate, and get the totient of each element.
         @♀ⁿ     Swap and take pow(<item in b>, <corresponding totient>)
            ♀%   Modulo each item by the remaining duplicate product on the stack.
                 Implicit return.

Une autre réponse basée sur ma réponse Python à 22 octets. Suggestions de golf bienvenues. Essayez-le en ligne!

;π╖`╝╛╜\╛r*"╛@%1="£░`M

Comment ça fonctionne

            Implicit input a.
;π╖         Duplicate, take product of a, and save to register 0.
`...`M      Map over a.
  ╝           Save the item, b, in register 1.
  ╛╜\         product(a) // b. Call it P.
  ╛r          Take the range [0...b].
  *           Multiply even item in the range by P. Call this list x.
  "..."£░     Turn a string into a function f.
              Push values of [b] where f returns a truthy value.
    ╛@%         Push b, swap, and push <item in x> % b.
    1=          Does <item> % b == 1?
            Implicit return.
Sherlock9
la source