Liniowy równanie diofantycznego dwóch zmiennych jest równanie postaci ax + by = C , gdzie , b oraz c są liczbami całkowitymi, stałe i x i y są liczbami całkowitymi zmiennych.
Dla wielu naturalnie występujących diofantyczne równania, x i y oznaczają ilości, które nie mogą być ujemne.
Zadanie
Napisać program lub funkcję, która przyjmuje współczynniki , b i c na wejściu i zwraca dowolną parę liczb naturalnych (0, 1, 2, ...), x i y to sprawdzenie równania ax + by = C , w razie takiej pary istnieje.
Dodatkowe zasady
Możesz wybrać dowolny format wejściowy i wyjściowy, który obejmuje tylko pożądane liczby całkowite i, opcjonalnie, tablicę / listę / macierz / krotkę / wektorową notację twojego języka, o ile nie osadzisz żadnego kodu na wejściu.
Można założyć, że współczynniki a i b są zarówno niezerową.
Twój kod musi działać dla każdej trojaczki liczb całkowitych od -2 60 do 2 60 ; na moim komputerze musi zakończyć się w niecałą minutę (Intel i7-3770, 16 GiB RAM).
Nie możesz używać żadnych wbudowanych rozwiązań, które rozwiązują równania diofantyczne, a tym samym trywializują to zadanie, takie jak Mathematica
FindInstance
lubFrobeniusSolve
.Twój kod może zachowywać się tak, jak chcesz, jeśli nie można znaleźć rozwiązania, o ile jest ono zgodne z limitem czasu, a jego wynik nie może być mylony z prawidłowym rozwiązaniem.
Obowiązują standardowe zasady gry w golfa .
Przykłady
Poniższe przykłady ilustrują prawidłowe operacje we / wy dla równania 2x + 3y = 11 , które ma dokładnie dwa prawidłowe rozwiązania ( (x, y) = (4,1) i (x, y) = (1,3) ).
Input: 2 3 11 Output: [4 1] Input: (11 (2,3)) Output: [3],(1)
Jedynym prawidłowym rozwiązaniem 2x + 3y = 2 jest para (x, y) = (1,0) .
Poniższe przykłady ilustrują prawidłowe operacje we / wy dla równania 2x + 3y = 1 , które nie ma prawidłowych rozwiązań .
Input: (2 3 1) Output: [] Input: 1 2 3 Output: -1 Input: [[2], [3], [1]] Output: (2, -1)
Dla (a, b, c) = (1152921504606846883, -576460752303423433, 1) wszystkie prawidłowe rozwiązania (x, y) spełniają to (x, y) = (135637824071393749 - bn, 271275648142787502 + an) dla pewnej liczby całkowitej nieujemnej n .
źródło
Odpowiedzi:
Pyth, 92 bajty
To całkiem potwór.
Wypróbuj online: demonstracja . Format wejściowy to,
c\n[a,b]
a format wyjściowy to[x,y]
.W przypadku, gdy nie istnieje żadne rozwiązanie liczb całkowitych, nic nie wydrukuję, aw przypadku, gdy nie istnieje naturalne rozwiązanie liczb całkowitych, po prostu wydrukuję losowe rozwiązanie liczb całkowitych.
Wyjaśnienie (zgrubny przegląd)
Najpierw znajdę całkowite rozwiązanie równania
ax + by = gcd(a,b)
za pomocą algorytmu Extended Euclidean.Następnie zmodyfikuję rozwiązanie (moje mnożenie
a
ib
przezc/gcd(a,b)
), aby uzyskać całkowite rozwiązanieax + by = c
. Działa to, jeślic/gcd(a,b)
jest liczbą całkowitą. W przeciwnym razie nie ma rozwiązania.Wszystkie inne rozwiązania całkowite mają postać
a(x+n*b/d) + b(y-n*a/d) = c
zd = gcd(a,b)
do liczby całkowitejn
. Używając dwóch nierównościx+n*b/d >= 0
iy-n*a/d >= 0
mogę określić 6 możliwych wartości dlan
. Spróbuję wszystkich 6 z nich i wydrukuję rozwiązanie o najwyższym najniższym współczynniku.Objaśnienie (szczegółowe)
Pierwszym krokiem jest znalezienie rozwiązania liczby całkowitej w równaniu
ax' + by' = gcd(a,b)
. Można tego dokonać za pomocą rozszerzonego algorytmu euklidesowego. Możesz dowiedzieć się, jak to działa na Wikipedii . Jedyna różnica polega na tym, że zamiast 3 kolumn (r_i s_i t_i
) użyję 6 kolumn (r_i-1 r_i s_i-1 s_i t_i-1 t_i
). W ten sposób nie muszę przechowywać ostatnich dwóch wierszy w pamięci, tylko ostatni.Teraz chcę znaleźć rozwiązanie
ax + by = c
. Jest to możliwe tylko wtedy, gdyc mod gcd(a,b) == 0
. Jeżeli równanie to jest spełnione, po prostu mnożącx',y'
sięc/gcd(a,b)
.Mamy rozwiązanie dla liczb całkowitych
ax + by = c
. Zauważmy, żex
,y
albo oba mogą być ujemne. Naszym celem jest więc przekształcenie ich w nieujemne.Zaletą równań diofantycznych jest to, że możemy opisać wszystkie rozwiązania za pomocą tylko jednego początkowego rozwiązania. Jeśli
(x,y)
to rozwiązanie, że wszelkie inne rozwiązania są formy(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
don
liczby całkowitej.Dlatego chcemy znaleźć
n
, gdziex-n*b/gcd(a,b) >= 0
iy+n*a/gcd(a,b >= 0
. Po pewnej transformacji powstają dwie nierównościn >= -x*gcd(a,b)/b
in >= y*gcd(a,b)/a
. Zauważ, że symbol nierówności może patrzeć w innym kierunku z powodu podziału z potencjalnym ujemnyma
lubb
. Nie dbam o to tak bardzo, po prostu mówię, że jedna liczba-x*gcd(a,b)/b - 1, -x*gcd(a,b)/b, -x*gcd(a,b)/b + 1
zdecydowanie spełnia nierówność 1, a jedna liczbay*gcd(a,b)/a - 1, y*gcd(a,b)/a, y*gcd(a,b)/a + 1
spełnia nierówność 2. Jest takan
, która zaspokaja obie nierówności, jedna z 6 liczb również.Następnie obliczam nowe rozwiązania
(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
dla wszystkich 6 możliwych wartościn
. I drukuję rozwiązanie o najwyższej najniższej wartości.Sortowanie według sortowanej kolejności działa w następujący sposób. Korzystam z tego przykładu
2x + 3y = 11
Sortuję każde z 6 rozwiązań (nazywane to kluczami), a oryginalne rozwiązania sortuję według kluczy:
To sortuje kompletne nieujemne rozwiązanie do końca (jeśli istnieje).
źródło
Matlab (660)
Wyjaśnienie:
kod przyjmuje trzy wejściowe niezmienniki a, b, c, te ostatnie są poddane kilku warunkom przed przystąpieniem do obliczania:
1- jeśli (a + b> c) i (a, b, c> 0) nie ma rozwiązania!
2- jeśli (a + b <c), (a, b, c <0) brak rozwiązania!
3- jeśli (a, b) mają wspólne przeciwne znaki c: brak rozwiązania!
4 - jeśli GCD (a, b) nie podzieli c, to znowu nie ma rozwiązania! , w przeciwnym razie podziel wszystkie warianty przez GCD.
po tym musimy sprawdzić inny warunek, powinien on ułatwić i skrócić drogę do pożądanego rozwiązania.
5- jeśli c podziel a lub b, rozwiązanie s = (x lub y) = (c- [ax, yb]) / [b, a] = C / [b, a] + [ax, yb] / [b , a] = S + [ax, yb] / [b, a], gdzie S jest naturalne, więc ax / b lub przez / a będą odtąd mieć nieujemne bezpośrednie rozwiązania, które odpowiednio wynoszą x = b lub y = a. (zauważ, że rozwiązania mogą być zerowymi wartościami w przypadku, gdy poprzednie arbitralne rozwiązania zostaną ujawnione jako negatywne)
gdy program osiąga ten etap, zamiana węższych rozwiązań dla x = (c-yb) / a jest zamiatana, dzięki zgodności, zamiatania większych zakresów liczb, które są powtarzane cyklicznie. największym polem wyszukiwania jest [xa, x + a], gdzie a jest dzielnikiem.
SPRÓBUJ
źródło
Aksjomat, 460 bajtów
golf i trochę testu
W innych możliwych „rozwiązaniach” wystąpił błąd, ponieważ próbował zapisać nieskończone rozwiązania na jednej liście; teraz jest narzucony limit maksymalnie 80 rozwiązań
źródło