L'identità di Bézout


11

Introduzione all'identità di Bézout

Il GCD di due numeri interi A, B è il numero intero positivo più grande che li divide entrambi senza lasciare resto. Ora a causa della proprietà di Euclide che ogni intero N può essere diviso per un altro intero M come segue:

                                           Divisione euclidea

esistono coppie u, v tali che possiamo scrivere:

                                           L'identità di Bézout

Poiché esiste una quantità infinita di quelle coppie, vorremmo trovarne di speciali. Esistono infatti esattamente (A, B che non è zero) due di queste coppie che si saturano

                                           Vincoli per coppie significative (u, v)


per esempio                                    Esempio con 19 e 17


Sfida

L'obiettivo di questa sfida è di trovare la coppia (ordinata) di coefficienti (u, v) che saturano i vincoli di cui sopra e dove devi essere positivo. Ciò restringe l'output a una coppia unica.


Ingresso

Possiamo supporre che l'ingresso sia positivo, inoltre A sarà sempre maggiore di B (A> B).


Produzione

L'output del nostro programma / funzione deve essere la coppia (ordinata) specificata nella sfida.


Regole

Non si devono usare algoritmi euclidi estesi incorporati (ad es. In Mathematica si può usare GCDma non ExtendedGCD- che fallirebbero comunque per 5,3).

La risposta può essere un programma completo (che accetta input tramite STDIN o simile e output tramite STDOUT) o una funzione (che restituisce la coppia).

Accanto alla coppia (u, v) non deve esserci alcun output, sono consentiti newline o spazi finali. (parentesi o virgole vanno bene)

Questo è il golf del codice, sono vietate tutte le scappatoie standard e vince il programma con il numero di byte più basso.


Esempi

(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)

Risposte:


1

MATL , 37 40 byte

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

Usa la versione (9.3.1) , che è precedente a questa sfida.

Questo è un approccio a forza bruta, quindi potrebbe non funzionare per input di grandi dimensioni.

Provalo online! Il compilatore online si basa su una versione più recente, ma produce gli stessi risultati.

Spiegazione

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 byte

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

Esempio di utilizzo: 27998 # 6461-> (3,-13).

Questo è un approccio di forza bruta che trova tutte le combinazioni di ue vche sono soluzioni valide ordinate da ue sceglie il primo. Questo richiede un po 'di tempo per funzionare in grande |v|.


Adoro l' []!!0idea =)
flawr

3

Pitone 3, 101 106 byte

Modifica: aggiunti alcuni miglioramenti e correzioni suggeriti da Bruce_Forte .

Una risposta che utilizza l'algoritmo euclideo esteso. È un po 'goffo in alcuni punti, e spero di giocarci ancora un po'. Potrei convertire in Python 2 per salvare un byte sulla divisione intera ( //) ma non sono sicuro di come l' %operatore del modulo di Python 2 funzioni con un secondo argomento negativo, dato che è cruciale per ottenere l'output corretto.

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)

Ungolfed:

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 utente anonimo ha sottolineato che la variabile knell'ultima riga della tua versione non controllata è indefinita.
Jonathan Frech,

@JonathanFrech Ah, grazie!
Sherlock9

1

Mathematica, 80 byte

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

Spiegazione :

L'algoritmo euclideo esteso viene utilizzato qui, in uno Neststile. Il metodo con cui i coefficienti sono memorizzati in array rende possibile l'uso Dot.

Un'altra possibile rappresentazione sta semplicemente usando l'espressione simbolica, come u a - v bcon {a->19, b->17}. Tale rappresentazione utilizza la funzionalità di Mathematica ed è interessante, ma è molto più lunga in byte.


Casi di prova :

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

1

Rubino, 83 byte

Penso che ci siano alcuni modi per mettere a punto e golfare questa soluzione, ma finora mi piace. Forse proverò dopo una soluzione di algoritmo euclideo estesa.

->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}

Come funziona

Questo codice inizia con un ciclo uda ygiù a 0, con un ciclo interno da vda -xa 0, all'interno del quale controlliamo ogni ue vse u*x+v*y == gcd(x, y). Dal momento che ci potrebbe essere più corrispondenze lungo la strada (Questo utilizza una ricerca molto esaustiva), si parte lontano da 0 in modo che quando si ottiene l'ultimo dei più corrispondenze, è quella in cui |u|e |v|sono più vicini a 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 Darn. L'IRB ha esaurito la memoria per quel test case. Scriverò appena possibile una soluzione di algoritmo euclideo estesa.
Sherlock9,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.