高校時代は手順がいまいち理解できていなかったので、自分なりにまとめてみようと思います。
場合分けが面倒なので、特に断りがなければ以下を前提とする。
方程式
の整数解は、整数
と表すことができる。
これを方程式に代入すると
step | 数式1 | 数式2 | |
---|---|---|---|
よって一般解は整数
※
具体例として
互除法 | ||
---|---|---|
上表より
一般解は
実践してみると分かるが、ベクトルの計算に必要な情報は各ステップにおける商のみ。
計算は割と簡単。
※途中で出てきた
互除法の途中で目的を達成できるときもあるので留意したい。
符号やらの関係でミスしがちなので、ミスを減らしつつコンパクトに計算する方法を考えたい。
とりあえず試作。
互除法の初期値
例:
互除法の結果より
筆算 試作
互除法のStep
「
みたいなことがいえる。
よって今回の計算は、mod演算における逆数っぽいものを求める操作とみることもできそう。
その意味や応用についてはよく分かりませんが、そのうち考えてみたいと思います。
計算用のpythonプログラム。
Jupyter Notebook
などで実行できる。
最終行の数字を適当に変更して実行すると演習に役立つかも。
import math
def euclidEx(a,b):
g=math.gcd(a,b)
if g>1:
print('互いに素な数を入力してください')
return
if abs(a)<abs(b):
tmp1=abs(b)
tmp2=abs(a)
#a=[1,0]、b=[0,1]とおく
#tmp1に相当するベクトル: v1
if(b<0):
v1=[0,-1]
else:
v1=[0,1]
#tmp2に相当するベクトル
if(a<0):
v2=[-1,0]
else:
v2=[1,0]
else:
tmp1=abs(a)
tmp2=abs(b)
#a=[1,0]、b=[0,1]とおく
#tmp1に相当するベクトル: v1
if(a<0):
v1=[-1,0]
else:
v1=[1,0]
#tmp2に相当するベクトル
if(b<0):
v2=[0,-1]
else:
v2=[0,1]
s=''
cnt=0
while tmp2>1:
q=tmp1//tmp2
r=tmp1%tmp2
v=[0,0]
v[0]=v1[0]-v2[0]*q
v[1]=v1[1]-v2[1]*q
s=s+str(tmp1)+'='+str(tmp2)+' × '+str(q)+' + '+str(r)+' \t'
s=s+'v_'+str(cnt)+'=' +str(v1)+' - '+str(v2)+ ' ・ ' + str(q)+'\t= '+str(v)+' \t'
s=s+polynominal(v,['a','b'])+' = '+ str(r)
s=s+'\n'
tmp1=tmp2
tmp2=r
v1=list(v2)
v2=list(v)
cnt=cnt+1
if cnt>100:
break
print(s)
def term(keisu,moji,isBegin):
#多項式の中の項を返す(符号、演算子を調整、係数が1のとき係数を削除)
absK=abs(keisu) #係数の絶対値
if absK==1:
absK=''
else:
absK=str(absK)
if(keisu)>0: #係数が正
if isBegin==True:
ope=''
sgn=''
else:
ope=' + '
sgn=''
result=ope+sgn+absK+moji
elif keisu<0: #係数が負
if isBegin==True:
ope=''
sgn='-'
else:
ope=' - '
sgn=''
result=ope+sgn+absK+moji
else: #係数が0
result=''
return result
def polynominal(k_lst,moji_lst):
#多項式を表す文字列を返す
result=''
for i in range(len(k_lst)):
if i==0:
result=result+term(k_lst[i],moji_lst[i],True)
else:
result=result+term(k_lst[i],moji_lst[i],False)
return result
#例
euclidEx(131,17)