Identidad de Bézout


11

Introducción a la identidad de Bézout.

El MCD de dos enteros A, B es el entero positivo más grande que los divide a ambos sin dejar ningún resto. Ahora, debido a la propiedad de Euclides, cada número entero N puede dividirse por otro número entero M de la siguiente manera:

                                           División euclidiana

existen pares u, v tal que podemos escribir:

                                           Identidad de Bézout

Como hay una cantidad infinita de esos pares, nos gustaría encontrar unos especiales. De hecho, hay exactamente (A, B no es cero) dos pares que satifican

                                           Restricciones para pares significativos (u, v)


p.ej                                    Ejemplo con 19 y 17


Desafío

El objetivo de este desafío es encontrar el par de coeficientes (ordenados) (u, v) que satisfacen las restricciones anteriores y donde debe ser positivo. Esto reduce la salida a un par único.


Entrada

Podemos suponer que la entrada es positiva, también A siempre será mayor que B (A> B).


Salida

La salida de nuestro programa / función debe ser el par (ordenado) especificado en el desafío.


Reglas

No se deben usar algoritmos euclidianos extendidos incorporados (por ejemplo, en Mathematica se permite usar GCDpero no ExtendedGCD, lo que de todos modos fallaría en 5,3).

La respuesta puede ser un programa completo (toma de entrada a través de STDIN o similar y salida a través de STDOUT) o una función (devolver el par).

Al lado del par (u, v) no habrá salida, se permiten nuevas líneas o espacios finales. (los corchetes o comas están bien)

Este es el código de golf, todas las lagunas estándar están prohibidas y el programa con el conteo de bytes más bajo gana.


Ejemplos

(A, B) -> (u, v)
(42, 12) -> (1, -3)
(4096, 84) -> (4, -195)
(5, 3) -> (2, -3)
(1155, 405) -> (20, -57)
(37377, 5204) -> (4365, -31351)
(7792, 7743) -> (7585, -7633)
(38884, 2737) -> (1707, -24251)
(6839, 746) -> (561, -5143)
(41908, 7228) -> (1104, -6401)
(27998, 6461) -> (3, -13)
(23780, 177) -> (20, -2687)
(11235813, 112358) -> (8643, -864301)

Respuestas:


1

MATL , 37 40 bytes

ZdXK2Gw/:1G*1GK/t_w2$:XI2G*!+K=2#fIb)

Utiliza la versión (9.3.1) , que es anterior a este desafío.

Este es un enfoque de fuerza bruta, por lo que puede no funcionar para entradas grandes.

Pruébalo en línea! El compilador en línea se basa en una versión más reciente, pero produce los mismos resultados.

Explicación

Zd            % implicitly input A and B. Compute their GCD. Call that C
XK            % copy C to clipboard K
2Gw/:         % vector [1, 2, ..., B/C]
1G*           % multiply that vector by A
1GK/t_w2$:    % vector [-A/C, -A/C+1 ..., A/C]
XI            % copy to clipboard I
2G*           % multiply that vector by B
!+            % all pairwise sums of elements from those vectors
K=2#f         % find row and column indices of sum that equals C
Ib)           % index second vector with column (indexing first vector with
              % row is not needed, because that vector is of the form [1, 2, ...])

7

Haskell, 51 bytes

a#b=[(u,-v)|v<-[1..],u<-[1..v],gcd a b==u*a-v*b]!!0

Ejemplo de uso: 27998 # 6461-> (3,-13).

Este es un enfoque de fuerza bruta que encuentra todas las combinaciones de uy vque son soluciones válidas ordenadas por uy elige la primera. Esto toma un tiempo para correr por grande |v|.


Me encanta la []!!0idea =)
flawr

3

Python 3, 101 106 bytes

Editar: se agregaron algunas mejoras y correcciones sugeridas por Bruce_Forte .

Una respuesta que utiliza el algoritmo euclidiano extendido. Sin embargo, es un poco torpe en algunos lugares, y espero jugar un poco más. Podría convertir a Python 2 para guardar un byte en la división entera ( //) pero no estoy seguro de cómo %funciona el operador de módulo de Python 2 con un segundo argumento negativo, ya que eso es crucial para obtener la salida correcta.

def e(a,b):
 r=b;x=a;s=z=0;t=y=1
 while r:q=x/r;x,r=r,x%r;y,s=s,y-q*s;z,t=t,z-q*t
 return y%(b/x),z%(-a/x)

Sin golf:

def e(a, b):
    r = b
    x = a    # becomes gcd(a, b)
    s = 0
    y = 1    # the coefficient of a
    t = 1
    z = 0    # the coefficient of b
    while r:
        q = x / r
        x, r = r, x % r
        y, s = s, y - q * s
        z, t = t, z - q * t
    return y % (b / x), z % (-a / x) # modulus in this way so that y is positive and z is negative

Un usuario anónimo señaló que la variable ken la última línea de su versión no protegida no está definida.
Jonathan Frech

@ JonathanFrech Ah, gracias!
Sherlock9

1

Mathematica, 80 bytes

f@l_:=Mod@@NestWhile[{Last@#,{1,-Quotient@@(#.l)}.#}&,{{1,0},{0,1}},Last@#.l>0&]

explicación :

El algoritmo euclidiano extendido se usa aquí, en un Nestestilo. El método que los coeficientes se almacenan en matrices hace posible su uso Dot.

Otra posible representación es simplemente usar expresiones simbólicas, como u a - v bwith {a->19, b->17}. Dicha representación hace uso de la función de Mathematica y es interesante, pero es mucho más larga en bytes.


Casos de prueba :

f[{5, 3}]              (* {2, -3} *)
f[{42, 12}]            (* {1, -3} *)
f[{11235813, 112358}]  (* {8643, -864301} *)

1

Ruby, 83 bytes

Creo que hay algunas maneras de afinar y desarrollar esta solución, pero hasta ahora me gusta. Tal vez intentaré una solución de algoritmo euclidiano extendido a continuación.

->x,y{a=b=0;y.downto(0).map{|u|(-x..0).map{|v|a,b=u,v if u*x+v*y==x.gcd(y)}};p a,b}

Cómo funciona

Este código se inicia con un bucle de udesde yabajo a 0, con un bucle interno de vpartir -xa 0, en cuyo interior, comprobamos todos uy vsi u*x+v*y == gcd(x, y). Ya que podría haber varias coincidencias en el camino (este utiliza una búsqueda muy exhaustiva), comenzamos lejos de 0 para que cuando lleguemos a la última de las múltiples coincidencias, es aquel en el que |u|y |v|están más cerca de 0.

def bezout(x,y)
  a=b=0
  y.downto(0).each do |u|
    (-x..0).each do |v|
      if u*x + v*y == x.gcd(y)
        a,b=u,v
      end
    end
  end
  p a,b
end

@Bruce_Forte Maldición. IRB se quedó sin memoria para ese caso de prueba. Escribiré una solución de algoritmo euclidiano extendido tan pronto como pueda.
Sherlock9
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.