확장 유클리드 알고리즘

1 minute read

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