LoginSignup
1
1

More than 5 years have passed since last update.

a*x + b*y = gcd(a,b) を解く、のヒント

Last updated at Posted at 2015-05-16

a*x + b*y = gcd(a,b) を解く のヒント。

例として $28x + 13y = gcd(28,13)$ で考えてみる。

  • もちろん他のやり方もあると思う
  • 以下では説明上、未知数を $x_{1}, x_{0}$ とする

ヒント1

元の式を「ある規則」で変形していくだけ。何か気づかない?

$28x_{1} + 13x_{0}$
$= ....$
$= ....$

  • なおよく覚えていないが、わたしは 5分ほどかかってやっとひらめいた

「ある規則」とは、もちろん「最大公約数」を求たときの有名なアルゴリズム。

  • というより、この問題のほうがそのアルゴリズムがよく分かる

ヒント2

少しやってみよう。

$28x_{1} + 13x_{0}$
$= (2\times13+2)x_{1} + 13x_{0}$
$= 13(2x_{1}+x_{0}) + 2x_{1}$
$= 13x_{2} + 2x_{1}$

  • ここで $(2x_{1}+x_{0})=x_{2}$ と置いた (この関係は忘れてかまわない)
  • 不思議なことに(もちろん当たり前なんだけど)、係数が小さくなっちゃた!
  • これを続けていくと‥‥

ヒント3

$28x_{1} + 13x_{0}$
$= 13x_{2} + 2x_{1}$
$= 2x_{3} + x_{2}$
$= 1x_{4} + 0x_{3}$
$= gcd(28,13) $ ~ 元の式の右辺

右の係数が 0 になったときの左の係数が、元の係数の最大公約数なので、
$gcd(28,13) =1$ が求まったことになる。

  • 従って $x_{4}=1$、$x_{3}$ は何でもよいので例えば $x_{3}=0$ とする
  • すると3行目 $2x_{3} + x_{2}=1$ から $x_{2}$ が分かり、2行目から $x_{1}$、 1行目から $x_{0}$ が求まる
  • 要するに $gcd$ が求まったら、今度は下から上へバックトラックしていけばよい
  • なお $x_{3}$ の値を変えると別の解が得られる

プログラム作成

では実際にプログラムを作ってみてください。
以下の3通りでやってみるとよい練習になるかも?

  • 表計算 ~ Excel, Google spreadsheet など
  • 再帰呼び出しを使う ~ 普通に書いて8ステップ、ワンライナーも可能
  • 再帰呼び出しを使わない

蛇足

これは算数の問題。
$28 \times \bigcirc - 13 \times \bigtriangleup = 1$ なら小学生でも分かる。(3/10 負の数を使わなくても解けるようにマイナスにした)
ガウス少年なら一瞬で解いたであろうが、日本の小・中学生にも解ける子がいるはず。

参考

bezout.js
// returns [x,y,g]
function bezout(a,b,yn, depth) {
    var res;
    if(b == 0) {
        res = [1, yn, a];
    } else {
        var rres = bezout(b, a%b, yn, depth+1);
        var y = (rres[2] - a * rres[1])/b;
        res = [rres[1], y, rres[2]];
    }
    return res;
}

// 実行は a, b と yn に整数を与えて depth=0 で呼び出すだけ
// yn は複数解のうちから1つだけ選択するため。とりあえず 0 でよい
var res = bezout(a,b,yn, 0);
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1