(続き)
もう一つ必要なのは r = a*□ + b*□ を作る式です
上で計算した例では2通りの順番で計算しましたが、
プログラムでやる場合は@→A→Bの順で計算したほうがよさそうです。
(B→A→@だと、互除法を全部計算してからなので、@ABの結果とかを全部配列とかに入れておかないと計算できません)
n番目の式まで計算した結果を
R_n = A * X_n + B * Y_n
と表せたとすると、
さっき書いた互除法の一般式CのR_(n-1)とR_(n-2)のところにこれを代入すれば、
R_n = R_(n-2) - R_(n-1) * D_n
= (A * X_(n-2) + B * Y_(n-2)) - (A * X_(n-1) + B * Y_(n-1)) * D_n
= A * (X_(n-2) - X_(n-1) * D_n) + B * (Y_(n-2) - Y_(n-1) * D_n)
と表せます。
よって、
X_n = X_(n-2) - X_(n-1) * D_n
Y_n = Y_(n-2) - Y_(n-1) * D_n
と計算できます。
次に必要なのは初期値。
つまり、R_0 を計算するのに R_(-1), R_(-2) が必要なのでこれをセットします。
A = B * D_0 + R_0 なので、
R_(-2) = A, X_(-2) = 1, Y_(-2) = 0
R_(-1) = B, X_(-1) = 0, Y_(-1) = 1
となります。
最後に計算が終わる時の処理です。
R_n = 0 になったら計算終わりです。
(R_(n-1) がAとBの最大公約数になる)
R_(n-1) = A * X_(n-1) + B * Y_(n-1) より、
左辺がCになるように両辺 C / R_(n-1) を掛ければ、
C = A * (X_(n-1) * C / R_(n-1)) + B * (Y_(n-1) * C / R_(n-1))
なので、答えは
X = X_(n-1) * C / R_(n-1)
Y = Y_(n-1) * C / R_(n-1)
以上のことをプログラムで書くとこうなります。
R,X,Yなどは配列変数を用意しなくても、
R_0, R_(-1), R_(-2) を普通の変数で用意して、
R_0の計算が終わったら R_0→R_(-1)→R_(-2) と中身を移動していけばいいですね。
Dについては計算途中に D_n を1つ使うだけなので D_(-1) や D_(-2) は不要です。
R2=A:X2=1:Y2=0
R1=B:X1=0:Y1=1
WHILE 1
D0=R2 DIV R1
R0=R2 MOD R1
IF R0==0 THEN BREAK
X0=X2-X1*D0
Y0=Y2-Y1*D0
R2=R1:R1=R0
X2=X1:X1=X0
Y2=Y1:Y1=Y0
WEND
X=X1*C/R1
Y=Y1*C/R1
?X,Y