확장 유클리드 알고리즘
objective
를 만족하는 x,y를 찾아보자!
motivation
기본적으로 유클리드 알고리즘은 다음과 같은 사실에 의존한다.
일때, 이 성립한다.
위와 같은 성질이 성립하기 때문에 나눗셈 정리를 반복 적용하여 최대공약수를 구할 수 있다.
구체적으로 다음과 같이 적어보자.
이때
가 성립하기 때문에 최대공약수를 구할수 있다.
이제 이 식을 조금 정리하면,(마지막 제외)
을 얻고, 이를 이제 에다가 까지 차례대로 대입하면 a와 b의 일차결합꼴로 나타낼수있음을 확인할수있다.
하지만 이 작업은 손으로 하기에는 너무 귀찮고 힘들다.. 역시 이런 작업은 컴퓨터한테 시키는게 정신건강에 좋을것이다.
algorithm
저 위에서 얻은 식과 두 수의 최대공약수는 두 수의 일차결합으로 나타낼수있다는 사실을 가지고 알고리즘을 얻어보자.
위에서 얻은 식을 토대로 다음과 같은 식을 얻을수있다.
그리고 각 이 0이 되면 이는 유클리드 알고리즘이 끝났다는 뜻이니 이를 탈출 조건으로 정해주면 되겠다.
그리고 이 식이 a와 b의 일차결합으로 나타내어짐을 보장하기 위하여 로 설정하자. 그러면 이기때문에 일차 결합으로 나타내어지고 따라서 나머지 들도 a와 b의 일차결합으로 나타내어질것이다.(귀납법으로 쉽게 증명가능.)
그리고 이기 때문에 언젠간 은 0에 도달한다.
그리고 각 들은 ax+by꼴로 나타내어지니 의 a의 계수를 b의 계수를 라고 두면,
로 둘수있고, 이를 점화식에 대입하면 의 점화식을 얻을수있다.
이제 위 식을 이용해서 그대로 코드로 옮겨주면 된다.
fn egcd(a: i32, b: i32) -> (i32,i32,i32) {
let (mut s, mut t, mut r) = (0,1,b);
let (mut old_s, mut old_t, mut old_r) = (1,0,a);
while r != 0 {
let q = old_r / r;
let new_r = old_r - q*r;
let new_s = old_s - q*s;
let new_t = old_t - q*t;
old_r = r;
r = new_r;
old_s = s;
s = new_s;
old_t = t;
t = new_t;
}
(old_r,old_s,old_t)
}
Leave a comment