正整数を変換する操作についての考察(2)を紹介します。
考察(2)
m桁の正整数a(1)に変換操作を行い、
を得たとする。m(2≦m≦7)について、繰り返しの起点となる値a(p),a(1)はつぎのようになる。
m桁の正整数における繰り返しの起点a(p),a(1)を求めるプログラムはつぎのようになる。
●考え方
①配列要素A(N)(1≦N≦10m-1)に正整数Nに変換操作を1回行って得られる値を
保存する。
②正整数X(1≦X≦10m-1)からスタートして変換操作を続けたときの正整数の推移
(a(1)→a(2)→a(3)→…→a(i)→…→a(p)→a(p+1)→…→a(q))を配列Aを
活用して調べる。
③正整数a(i)の出現した順番iを配列B(a(i))に保存していき、2度目に
出現したとき、繰り返しの起点とする。
④得られた繰り返しの起点は、配列Cに重複しないように保存する。
⑤配列Cに保存された起点を表示する。
●プログラム(N6174c.bas)
' << N6174c.bas >> ' Tiny Basic ' ' 繰り返しの起点を探索。 ' Dim A(9999999): ' A(N):正整数Nに変換操作を1回行って得られる値。 Dim B(9999999): ' 変換操作で得られる正整数の順番を保存する配列。 Dim C(99): ' 起点を保存する配列。 Dim D(9): ' 正整数の各桁を保存する配列。 ' ' 桁数Mの設定。 For M=2 To 7 ' N1=1: ' M桁の正整数の最小数。 N2=10^M-1: ' M桁の正整数の最大数。 ' ' 配列A(*)を求める。 For N=N1 To N2 ' T0=N: ' 変換操作前の正整数T0。 ' ' 整数Nを各桁に分解し、配列D(*)に保存。Kは桁数。 T=T0: K=0 While T > 0 K=K+1: D(K)=T Mod 10: T=Int(T/10) Wend ' TがM桁未満の場合、0を補う。 While K < M: K=K+1: D(K)=0: Wend ' ' 配列D(*)の要素を昇順に並べる。 For I=K To 1 Step -1 For J=1 To I-1 If D(J) > D(J+1) Then W=D(J): D(J)=D(J+1): D(J+1)=W End If Next J Next I ' ' 最大数MAXNを求める。 MAXN=0 For I=K To 1 Step -1: MAXN=MAXN*10+D(I): Next I ' ' 最小数MINNを求める。 MINN=0 For I=1 To K: MINN=MINN*10+D(I): Next I ' ' 変換操作後の正整数T1:最大値-最小値 T1=MAXN-MINN ' A(T0)=T1 Next N ' ' 繰り返しの起点Xを求める。 B(0)=0 For I=N1 To N2: B(I)=0: Next I ' K=0: C(0)=0 For I=N1 To N2 X=I J=0: ' 変換操作の回数。 While B(X) = 0: J=J+1: B(X)=J X=A(X) Wend ' ' 起点Xの値を重複を除いて保存する。 IND=0 For L=0 To K If C(L) = X Then IND=1: Exit For Next L If IND = 0 Then L=K While X < C(L): C(L+1)=C(L): L=L-1: Wend If X > C(L) Then C(L+1)=X: K=K+1 End If ' ' 配列B(*)をリセット。 X=I: While B(X) > 0: B(X)=0: X=A(X): Wend Next I ' ' 結果の表示。 Print M;"桁の正整数" For L=1 To K Print C(L); Next L Print: Print Next M End
実行結果