Identitas Bézout


11

Pengantar identitas Bézout

GCD dari dua bilangan bulat A, B adalah bilangan bulat positif terbesar yang membagi keduanya tanpa meninggalkan sisa. Sekarang karena properti Euclid bahwa setiap bilangan bulat N dapat dibagi dengan bilangan bulat M lainnya sebagai berikut:

                                           Divisi Euclidean

ada pasangan u, v sehingga kita bisa menulis:

                                           Identitas Bézout

Karena ada jumlah tak terbatas dari pasangan itu, kami ingin mencari pasangan istimewa. Sebenarnya ada persis (A, B tidak menjadi nol) dua pasangan yang memuaskan

                                           Batasan untuk pasangan (u, v) yang bermakna


misalnya                                    Contoh dengan 19 dan 17


Tantangan

Tujuan dari tantangan ini adalah untuk menemukan pasangan (diperintahkan) koefisien (u, v) yang memuaskan kendala di atas dan di mana Anda harus positif. Ini mempersempit output ke pasangan unik.


Memasukkan

Kita dapat berasumsi bahwa inputnya positif, juga A akan selalu lebih besar dari B (A> B).


Keluaran

Output dari program / fungsi kami harus merupakan pasangan (dipesan) yang ditentukan dalam tantangan.


Aturan

Seseorang tidak boleh menggunakan algoritma Euclidean tambahan bawaan (misalnya dalam Mathematica, seseorang diizinkan untuk menggunakan GCDtetapi tidak ExtendedGCD- yang akan gagal selama 5,3).

Jawabannya mungkin program penuh (mengambil input melalui STDIN atau serupa dan output melalui STDOUT) atau fungsi (mengembalikan pasangan).

Di samping pasangan (u, v) tidak akan ada output, membuntuti baris baru atau spasi diperbolehkan. (kurung atau koma baik-baik saja)

Ini adalah kode golf, semua celah standar dilarang dan program dengan jumlah byte terendah akan menang.


Contohnya

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

Jawaban:


1

MATL , 37 40 byte

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

Menggunakan rilis (9.3.1) , yang lebih awal dari tantangan ini.

Ini adalah pendekatan brute force, jadi mungkin tidak bekerja untuk input besar.

Cobalah online! Kompiler online didasarkan pada rilis yang lebih baru, tetapi menghasilkan hasil yang sama.

Penjelasan

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

Contoh penggunaan: 27998 # 6461-> (3,-13).

Ini adalah pendekatan brute force yang menemukan semua kombinasi udan vyang merupakan solusi yang valid yang dipesan oleh udan memilih yang pertama. Ini membutuhkan waktu untuk dijalankan secara besar-besaran |v|.


Saya suka []!!0ide =)
flawr

3

Python 3, 101 106 byte

Sunting: Menambahkan beberapa perbaikan dan koreksi yang disarankan oleh Bruce_Forte .

Jawaban yang menggunakan algoritma Euclidean yang diperluas. Ini agak kikuk di beberapa tempat, dan saya berharap bisa bermain golf lagi. Saya dapat mengkonversi ke Python 2 untuk menyimpan byte pada integer division ( //) tapi saya tidak yakin bagaimana %operator modulus Python 2 bekerja dengan argumen kedua negatif, karena itu sangat penting untuk mendapatkan output yang benar.

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)

Tidak Disatukan:

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

Seorang pengguna anonim menunjukkan bahwa variabel kdi baris terakhir versi yang tidak Anda undefined tidak ditentukan.
Jonathan Frech

@ JonathanFrech Ah, terima kasih!
Sherlock9

1

Mathematica, 80 byte

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

Penjelasan :

Algoritma Extended Euclidean digunakan di sini, dalam Nestgaya. Metode dimana koefisien disimpan dalam array memungkinkan untuk digunakan Dot.

Representasi lain yang mungkin adalah hanya menggunakan ekspresi simbolis, seperti u a - v bdengan {a->19, b->17}. Representasi seperti itu menggunakan fitur Mathematica dan menarik, tetapi jauh lebih lama dalam byte.


Kasus uji :

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

1

Ruby, 83 byte

Saya pikir ada beberapa cara untuk menyempurnakan dan golf solusi ini, tapi saya sangat menyukainya. Mungkin saya akan mencoba solusi algoritma Euclidean selanjutnya.

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

Bagaimana itu bekerja

Kode ini dimulai dengan loop udari ybawah ke 0, dengan loop dalam dari vdari -xke 0, di dalamnya kita memeriksa setiap udan vjika u*x+v*y == gcd(x, y). Karena mungkin ada beberapa kecocokan di sepanjang jalan (ini menggunakan pencarian yang sangat lengkap), kami mulai jauh dari 0 sehingga ketika kami mendapatkan yang terakhir dari beberapa kecocokan, itu adalah yang mana |u|dan |v|yang paling dekat dengan 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. IRB kehabisan memori untuk test case itu. Saya akan menulis solusi algoritma Euclidean yang diperluas secepat mungkin.
Sherlock9
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.