Идентичность Безу


11

Введение в личность Безу

GCD из двух целых чисел A, B является наибольшим положительным целым числом, которое разделяет их обоих, не оставляя остатка. Теперь из-за свойства Евклида, что каждое целое число N может быть разделено на другое целое число M следующим образом:

                                           Евклидово подразделение

существуют пары u, v такие, что мы можем написать:

                                           Идентичность Безу

Поскольку таких пар бесконечно много, мы бы хотели найти специальные. На самом деле есть ровно (A, B не ноль) две такие пары, которые

                                           Ограничения для значимых (u, v) -пар


например                                    Пример с 19 и 17


Вызов

Цель этой задачи - найти (упорядоченную) пару коэффициентов (u, v), которые удовлетворяют вышеуказанным ограничениям и где u должно быть положительным. Это сужает вывод до уникальной пары.


вход

Можно предположить, что вход положительный, также A всегда будет больше, чем B (A> B).


Выход

Выход нашей программы / функции должен быть (упорядоченной) парой, указанной в запросе.


правила

Нельзя использовать встроенные расширенные евклидовы алгоритмы (например, в Mathematica можно использовать, GCDно нельзя ExtendedGCD- что в любом случае не сработает для 5,3).

Ответом может быть полная программа (получение ввода через STDIN или аналогичное и вывод через STDOUT) или функция (возвращающая пару).

Рядом с парой (u, v) не должно быть выходных данных, допускаются завершающие символы новой строки или пробелы. (скобки или запятые в порядке)

Это код гольф, все стандартные лазейки запрещены, и выигрывает программа с наименьшим количеством байтов.


Примеры

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

Ответы:


1

MATL , 37 40 байт

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

Использует релиз (9.3.1) , который является более ранним, чем этот вызов.

Это метод грубой силы, поэтому он может не работать для больших затрат.

Попробуйте онлайн! Онлайн-компилятор основан на более новой версии, но дает те же результаты.

объяснение

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 байт

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

Пример использования: 27998 # 6461-> (3,-13).

Это метод грубой силы, который находит все комбинации uи vкоторые являются действительными решениями, упорядоченными uи выбирает первое. Это займет некоторое время, чтобы баллотироваться |v|.


Я люблю []!!0идею =)
flawr

3

Python 3, 101 106 байт

Изменить: Добавлены некоторые улучшения и исправления, предложенные Bruce_Forte .

Ответ, который использует расширенный евклидов алгоритм. Хотя местами это немного неуклюже, и я надеюсь еще поиграть в гольф. Я мог бы преобразовать в Python 2, чтобы сохранить байт в целочисленном делении ( //), но я не уверен, как %оператор модуля Python 2 работает с отрицательным вторым аргументом, поскольку это крайне важно для получения правильного вывода.

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

Анонимный пользователь указал, что переменная kв последней строке вашей разглаженной версии не определена.
Джонатан Фрех

@JonathanFrech Ах, спасибо!
Sherlock9

1

Mathematica, 80 байт

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

Пояснение :

Расширенный евклидов алгоритм используется здесь, в Nestстиле. Метод, которым коэффициенты хранятся в массивах, позволяет использовать Dot.

Другое возможное представление - просто использование символического выражения, например, u a - v bс {a->19, b->17}. Такое представление использует функцию Mathematica и интересно, но оно намного длиннее в байтах.


Тестовые случаи :

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

1

Рубин, 83 байта

Я думаю, что есть несколько способов отрегулировать и отыграть это решение, но оно мне пока нравится. Может быть, я попробую решение расширенного евклидова алгоритма дальше.

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

Как это работает

Этот код начинается с цикла uот y0 до 0, с внутреннего цикла vот -x0 до, внутри которого мы проверяем каждый uи vесли u*x+v*y == gcd(x, y). Поскольку на этом пути может быть несколько совпадений (при этом используется очень исчерпывающий поиск), мы начинаем далеко от 0, поэтому, когда мы получаем последнее из нескольких совпадений, это то, где |u|и оно |v|ближе всего к 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 исчерпал память для этого теста. Я напишу решение расширенного евклидового алгоритма, как только смогу.
Sherlock9
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.