Una fórmula para congruencias


10

El teorema del resto chino puede ser bastante útil en aritmética modular.

Por ejemplo, considere el siguiente conjunto de relaciones de congruencia:

Conjunto de congruencia

Para conjuntos de relaciones de congruencia como esta, donde todas las bases ( 3, 5, 7en este ejemplo) son primas entre sí, habrá un y solo un número entero nentre 1y el producto de las bases ( 3*5*7 = 105en este ejemplo) inclusivo que satisfaga las relaciones .

En este ejemplo, el número sería 14generado por esta fórmula:

fórmula

donde 2, 4, and 0se dan del ejemplo anterior.

70, 21, 15son los coeficientes de la fórmula y que dependen de las bases, 3, 5, 7.

Para calcular los coeficientes de la fórmula ( 70, 21, 15en nuestro ejemplo) para un conjunto de bases, utilizamos el siguiente procedimiento.

Para cada número aen un conjunto de bases:

  1. Encuentre el producto de todas las otras bases, denotado como P.
  2. Encuentra el primer múltiplo de Peso deja un resto de 1cuando se divide por a. Este es el coeficiente de a.

Por ejemplo, para calcular el coeficiente que corresponde a la base 3, encontramos el producto de todas las demás bases (es decir 5*7 = 35) y luego encontramos el primer múltiplo de ese producto que deja un resto 1cuando se divide por la base.

En este caso, 35deja un resto de 2cuando se divide por 3, pero 35*2 = 70deja un resto de 1cuando se divide por 3, así 70es el coeficiente correspondiente para 3. Del mismo modo, 3*7 = 21deja un resto de 1cuando se divide por 5y 3*5 = 15deja un resto de 1cuando se divide por 7.

En una palabra

Para cada número aen un conjunto de números:

  1. Encuentre el producto de todos los otros números, denotados como P.
  2. Encuentra el primer múltiplo de Peso deja un resto de 1cuando se divide por a. Este es el coeficiente de a.

El reto

  • El desafío es, para un conjunto de dos o más bases, encontrar el conjunto de coeficientes correspondientes.
  • Se garantiza que el conjunto de bases será co-prime por pares y se garantiza que cada base sea mayor que 1.
  • Su entrada es una lista de enteros como entrada [3,4,5]o cadena separada por espacios "3 4 5"o, sin embargo, sus entradas funcionan.
  • Su salida debe ser una lista de enteros o una cadena separada por espacios que denota el conjunto de coeficientes.

Casos de prueba

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]

Muchas gracias a Leaky Nun por su ayuda al escribir este desafío. Como siempre, si el problema no está claro, hágamelo saber. ¡Buena suerte y buen golf!


¿Habrá siempre 3 números en la entrada?
xnor

@xnor Nope. Casos de prueba editados.
Sherlock9

Respuestas:


5

Haskell, 61 55 53 bytes

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

Define una función fque toma entrada y da salida como una lista de enteros.

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

Primero hacemos un bucle sobre todos los enteros en la entrada (1). Luego tomamos el producto de todos los enteros (2) y dividimos entre n para obtener solo el producto de los no nenteros, que es P(3).

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

Luego usamos el resultado ( P) como el valor del paso para un rango que comienza en cero (4). Tomamos el resultado, [0, P, 2P, 3P, ...]y lo filtramos en valores para los cuales el resultado de una operación mod-n es uno (5). Finalmente, tomamos el primer elemento, que funciona gracias a la evaluación diferida (6).

¡Gracias a @xnor por 2 bytes!


1
Bienvenido a Haskell! Creo que tu quotpuedes ser divy headpuedes ser !!0.
xnor

4

Jalea , 11 7 bytes

P:*ÆṪ%P

Pruébalo en línea! o verificar todos los casos de prueba .

Antecedentes

Deje que P y a sean estrictamente positivos, enteros coprimos .

La siguiente ecuación de congruencia puede describir el proceso de dos pasos en la pregunta: encontrar un múltiplo de P que deja un resto de 1 cuando se divide entre a .

ecuación de congruencia lineal

Según el teorema de Euler-Fermat , tenemos

Teorema de Euler-Fermat

donde φ denota la función totient de Euler . De este resultado, deducimos lo siguiente.

fórmula para la ecuación de congruencia lineal

Finalmente, dado que el desafío requiere que calculemos Px , observamos que

fórmula para el resultado final

donde Pa puede calcularse como el producto de todos los módulos.

Cómo funciona

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.

2

J, 13 bytes

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

Basado en la sorprendente respuesta de @Dennis .

Uso

Algunos casos de prueba necesitarán la entrada como enteros extendidos que tienen un sufijo 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

Explicación

*/|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

Pruébalo aquí.




1

Jalea, 14 13 bytes

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

¡Ahorré un byte gracias a @ Dennis !

Utiliza el proceso descrito en la especificación de desafío. La entrada es una lista de bases y la salida es una lista de coeficientes.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación

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

1

JavaScript (ES6), 80 bytes

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

Probé el algoritmo euclidiano extendido pero toma 98 bytes:

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 todos los valores son primos, ES7 puede hacerlo en 56 bytes:

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

1

Python + SymPy, 71 bytes

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

Esto usa el algoritmo de mi respuesta Jelly . I / O está en forma de listas de números SymPy.


1

Python 2, 87 84 bytes

Una implementación simple del algoritmo. Sugerencias de golf bienvenidas.

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]

Un programa completo ahorraría 3 bytes.
Dennis


0

GAP , 51 bytes

GAP tiene una función que puede calcular el ejemplo motivador ChineseRem([2,5,7],[2,4,0]), pero que aún así no hace que sea tan fácil obtener los coeficientes. Podemos obtener el enésimo coeficiente usando la lista con un uno en la enésima posición y ceros en las otras posiciones como segundo argumento. Por lo tanto, debemos crear estas listas y aplicar la función a todas ellas:

l->List(Basis(Integers^Size(l)),b->ChineseRem(l,b))

0

Lote, 148 bytes

@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%

0

En realidad, 14 bytes

Esto usa el algoritmo en la respuesta de Dennis's Jelly . Otra respuesta basada en mi respuesta de Python está por llegar. Sugerencias de golf bienvenidas. Pruébalo en línea!

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

Cómo funciona

                 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.

Otra respuesta basada en mi respuesta de Python a 22 bytes. Sugerencias de golf bienvenidas. Pruébalo en línea!

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

Cómo funciona

            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.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.