Persamaan Diophantine linier dalam dua variabel adalah persamaan bentuk ax + by = c , di mana a , b dan c adalah bilangan bulat konstan dan x dan y adalah variabel bilangan bulat.
Untuk banyak persamaan Diophantine yang terjadi secara alami, x dan y mewakili jumlah yang tidak boleh negatif.
Tugas
Tulis sebuah program atau fungsi yang menerima koefisien a , b dan c sebagai input dan mengembalikan sepasang bilangan asli (0, 1, 2, ...) x dan y yang memverifikasi persamaan kapak + dengan = c , jika pasangan tersebut ada
Aturan tambahan
Anda dapat memilih format apa pun untuk input dan output yang hanya melibatkan bilangan bulat yang diinginkan dan, secara opsional, larik / daftar / matriks / notasi / vektor notasi bahasa Anda, selama Anda tidak menanamkan kode apa pun dalam input.
Anda dapat mengasumsikan bahwa koefisien a dan b keduanya bukan nol.
Kode Anda harus bekerja untuk setiap triplet bilangan bulat antara -2 60 dan 2 60 ; itu harus selesai di bawah satu menit di komputer saya (Intel i7-3770, 16 GiB RAM).
Anda tidak boleh menggunakan built-in yang memecahkan persamaan Diophantine dan karenanya meremehkan tugas ini, seperti Mathematica
FindInstance
atauFrobeniusSolve
.Kode Anda mungkin berperilaku namun Anda inginkan jika tidak ada solusi yang ditemukan, asalkan sesuai dengan batas waktu dan hasilnya tidak dapat dikacaukan dengan solusi yang valid.
Aturan standar kode-golf berlaku.
Contohnya
Contoh di bawah ini menggambarkan I / O yang valid untuk persamaan 2x + 3y = 11 , yang memiliki tepat dua solusi yang valid ( (x, y) = (4,1) dan (x, y) = (1,3) ).
Input: 2 3 11 Output: [4 1] Input: (11 (2,3)) Output: [3],(1)
Satu-satunya solusi yang valid dari 2x + 3y = 2 adalah pasangan (x, y) = (1,0) .
Contoh di bawah ini menggambarkan I / O yang valid untuk persamaan 2x + 3y = 1 , yang tidak memiliki solusi yang valid .
Input: (2 3 1) Output: [] Input: 1 2 3 Output: -1 Input: [[2], [3], [1]] Output: (2, -1)
Untuk (a, b, c) = (1152921504606846883, -576460752303423433, 1) , semua solusi yang benar (x, y) memenuhi bahwa (x, y) = (135637824071393749 - bn, 271275648142787502 + an) untuk beberapa non-negatif bilangan bulat n .
sumber
Jawaban:
Pyth, 92 byte
Itu monster.
Cobalah online: Peragaan . Format input adalah
c\n[a,b]
dan format output[x,y]
.Dalam hal tidak ada solusi integer, saya tidak akan mencetak apa pun, dan dalam hal tidak ada solusi integer alami, saya hanya akan mencetak solusi integer acak.
Penjelasan (Ikhtisar Kasar)
Pada awalnya saya akan menemukan solusi integer untuk persamaan
ax + by = gcd(a,b)
dengan menggunakan algoritma Extended Euclidean.Kemudian saya akan memodifikasi solusi (pengali
a
danb
dengan sayac/gcd(a,b)
) untuk mendapatkan solusi integerax + by = c
. Ini berfungsi, jikac/gcd(a,b)
bilangan bulat. Kalau tidak, tidak ada solusi.Semua solusi integer lainnya memiliki formulir
a(x+n*b/d) + b(y-n*a/d) = c
dengand = gcd(a,b)
untuk integern
. Menggunakan dua ketidaksetaraanx+n*b/d >= 0
dany-n*a/d >= 0
saya bisa menentukan 6 nilai yang mungkin untukn
. Saya akan mencoba semuanya dan mencetak solusinya dengan koefisien terendah tertinggi.Penjelasan (Detail)
Langkah pertama adalah menemukan solusi integer untuk persamaan tersebut
ax' + by' = gcd(a,b)
. Ini dapat dilakukan dengan menggunakan algoritma Euclidean yang diperluas. Anda bisa mendapatkan ide tentang cara kerjanya di Wikipedia . Satu-satunya perbedaan adalah, bahwa alih-alih menggunakan 3 kolom (r_i s_i t_i
) saya akan menggunakan 6 kolom (r_i-1 r_i s_i-1 s_i t_i-1 t_i
). Dengan cara ini saya tidak harus menyimpan dua baris terakhir dalam memori, hanya yang terakhir.Sekarang saya ingin mencari solusinya
ax + by = c
. Ini hanya mungkin, ketikac mod gcd(a,b) == 0
. Jika persamaan ini puas, saya hanya mengalikanx',y'
denganc/gcd(a,b)
.Kami memiliki solusi integer untuk
ax + by = c
. Perhatikan, bahwax
,y
atau keduanya mungkin negatif. Jadi tujuan kami adalah mengubahnya menjadi non-negatif.Hal yang menyenangkan tentang persamaan Diophantine adalah, kita dapat menggambarkan semua solusi hanya dengan menggunakan satu solusi awal. Jika
(x,y)
solusi, bahwa semua solusi lainnya adalah dari bentuk(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
untukn
integer.Karena itu kami ingin mencari
n
, di manax-n*b/gcd(a,b) >= 0
dany+n*a/gcd(a,b >= 0
. Setelah beberapa transformasi kita berakhir dengan dua ketidaksetaraann >= -x*gcd(a,b)/b
dann >= y*gcd(a,b)/a
. Perhatikan bahwa simbol ketimpangan mungkin melihat ke arah lain karena pembagian dengan potensi negatifa
ataub
. Saya tidak terlalu peduli tentang hal itu, saya hanya mengatakan bahwa satu angka-x*gcd(a,b)/b - 1, -x*gcd(a,b)/b, -x*gcd(a,b)/b + 1
pasti memuaskan ketidaksetaraan 1, dan satu angkay*gcd(a,b)/a - 1, y*gcd(a,b)/a, y*gcd(a,b)/a + 1
memuaskan ketidaksetaraan 2. Adan
, yang memenuhi kedua ketidaksetaraan, salah satu dari 6 angka juga.Lalu saya menghitung solusi baru
(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
untuk semua 6 nilai yang mungkin darin
. Dan saya mencetak solusinya dengan nilai terendah tertinggi.Urutkan berdasarkan urutan pesanan mereka berfungsi dengan cara berikut. Saya menggunakan contohnya
2x + 3y = 11
Saya mengurutkan masing-masing dari 6 solusi (ini disebut kunci), dan mengurutkan solusi asli dengan kunci mereka:
Ini semacam solusi non-negatif lengkap sampai akhir (jika ada).
sumber
Matlab (660)
Penjelasan:
kode mengambil tiga invarian a, b, c sebagai input, yang terakhir ini ditundukkan ke beberapa kondisi sebelum melanjutkan untuk menghitung:
1- jika (a + b> c) dan (a, b, c> 0) tidak ada solusi!
2- jika (a + b <c), (a, b, c <0) tidak ada solusi!
3 - jika (a, b) memiliki tanda kebalikan yang sama dari c: tidak ada solusi!
4 - jika GCD (a, b) dosnt membagi c, maka tidak ada solusi lagi! , jika tidak, bagi semua varian dengan GCD.
setelah ini, kita harus memeriksa kondisi lain, itu harus memudahkan dan mempersingkat jalan menuju solusi yang diinginkan.
5- jika c membagi a atau b, solusi s = (x atau y) = (c- [kapak, yb]) / [b, a] = C / [b, a] + [kapak, yb] / [b , a] = S + [kapak, yb] / [b, a] di mana S adalah alami sehingga kapak / b atau oleh / a akan memiliki solusi langsung selanjutnya non-negatif yang masing-masing x = b atau y = a. (perhatikan bahwa solusi dapat hanya bernilai nihil jika solusi arbitrer sebelumnya dinyatakan negatif)
ketika program mencapai tahap ini, serangkaian solusi yang lebih sempit untuk x = (c-yb) / a malah disapu, berkat kongruensi, menyapu rentang angka yang lebih besar, yang datang secara berulang-ulang dengan siklus reguler. bidang pencarian terbesar adalah [xa, x + a] dengan a adalah pembagi.
COBALAH
sumber
Aksioma, 460 byte
ungolf dan beberapa tes
Di 'solusi' lain yang mungkin ada bug karena mencoba menyimpan solusi tak terbatas dalam satu Daftar; sekarang diberlakukan batas 80 solusi maks
sumber