コラッツ演算しないでコラッツ一般項を使って計算する
実行結果は、下のように奇数のみの演算結果を出力します。
でも、3かけて1を足したり、2で割ったり…はしていません。
した方が早いですけれどね
一般項を用いて、ひたすら計算しました(させました)。
これは、一般項が合っていますよ~という答え合わせになりますね
PS C:\Users\default\python> python colla_cal ↵
2桁までのすきな奇数を入力してください:11 ↵
奇数のみのコラッツ計算: [11, 17, 13, 5, 1]
PS C:\Users\default\python> python colla_cal ↵
2桁までのすきな奇数を入力してください:13 ↵
奇数のみのコラッツ計算: [13, 5, 1]
PS C:\Users\default\python> python colla_cal ↵
2桁までのすきな奇数を入力してください:27 ↵
奇数のみのコラッツ計算: [27, 41, 31, 47, 71, 107, 161, 121, 91,
137, 103, 155, 233, 175, 263, 395, 593, 445, 167, 251, 377, 283,
425, 319, 479, 719, 1079, 1619, 2429, 911, 1367, 2051, 3077, 577,
433, 325, 61, 23, 35, 53, 5, 1]
PS C:\Users\default\python> python colla_cal ↵
2桁までのすきな奇数を入力してください:55 ↵
奇数のみのコラッツ計算: [55, 83, 125, 47, 71, 107, 161, 121, 91,
137, 103, 155, 233, 175, 263, 395, 593, 445, 167, 251, 377, 283,
425, 319, 479, 719, 1079, 1619, 2429, 911, 1367, 2051, 3077, 577,
433, 325, 61, 23, 35, 53, 5, 1]
#--------------------------------------------------------------
# 一般項により奇数を計算し、s,tの値とともにリスト作成
# リストから奇数を検索して求めたs,tより次の奇数を計算
# 1になるまで繰り返す
#--------------------------------------------------------------
n = 513 # 計算するtの上限
m = 4 # 計算するsの上限
num_i = int(input('2桁までのすきな奇数を入力してください:'))
odd_list = [] # 奇数リストを用意
#=======奇数eを計算し、s,tの値とともにリストに追加=======
for t in range(1, n+1): # tを指定
for s in range(1, m+1): # sを指定
tmp = int((4 ** (s - 1) * 4 - 1) / 3 + 8 * (t - 1) * 4 ** (s - 1) )
if tmp < 10000: #4桁以下の奇数だけリストにする
odd_sublist_e = [] #奇数サブリストeを用意
odd_sublist_e.append(tmp)
odd_sublist_e.append(s)
odd_sublist_e.append(t)
odd_sublist_e.append(0)
odd_list. append(odd_sublist_e) # 奇数サブリストe[奇数e,s,t,0]を奇数リストに追加
#=======奇数oを計算し、s,tの値とともにリストに追加=======
for t in range(1, n+1): # tを指定
for s in range(1, m+1): # sを指定
tmp = int( (4 ** (s - 1) * 10 - 1) / 3 + 4 * (t - 1) * 4 ** (s - 1) )
if tmp < 10000: #4桁以下の奇数だけリストにする
odd_sublist_o = [] #奇数サブリストoを用意
odd_sublist_o.append(tmp)
odd_sublist_o.append(s)
odd_sublist_o.append(t)
odd_sublist_o.append(1)
odd_list. append(odd_sublist_o) # 奇数サブリストo[奇数e,s,t,1]を奇数リストに追加
odd_list = sorted(odd_list) # 奇数リストを1列目の奇数で昇順にソート
#print(odd_list)
list_i = [] # 奇数が一致したときの配列を入れるリストを用意
list_cal = [] # 計算結果を入れるリストを用意
list_cal.append(num_i) # 入力した奇数を計算結果リストに追加
while num_i != 1: # num_iが1になるまで処理する
list_i = list(filter(lambda x: x[0] == num_i, odd_list)) #1列目がnum_iである配列を取得
if list_i == []: #エラー処理
print("******* error_******* num_i: " + str(num_i))
break
t_i = int(list_i[0][2]) #list_iからtの値を取得
s_i = int(list_i[0][1]) #list_iからsの値を取得
if num_i == (4 ** (s_i - 1) * 4 - 1) / 3 + 8 * (t_i - 1) * 4 ** (s_i - 1) : #eの式の奇数である場合
num_inext = 6 * t_i - 5 # 次の奇数を計算
list_cal.append(num_inext) # 求めた奇数を計算結果リストに追加
else: # oの式の奇数である場合
num_inext = 6 * t_i - 1 # 次の奇数を計算
list_cal.append(num_inext) # 求めた奇数を計算結果リストに追加
num_i = num_inext # num_iに求めた奇数をセット
print("奇数のみのコラッツ計算: " + str(list_cal))
計算方法
まず、s,tの値を1から順に一般項に代入して奇数を計算し、参照するためのリストを作成します。
[[1, 1, 1, 0], [5, 2, 1, 0], [21, 3, 1, 0], [85, 4, 1, 0], [9, 1, 2, 0],
[37, 2, 2, 0], [149, 3, 2, 0], [597, 4, 2, 0], [17, 1, 3, 0], [69, 2, 3, 0],
[277, 3, 3, 0], [1109, 4, 3, 0], [25, 1, 4, 0], [101, 2, 4, 0], [405, 3, 4, 0],
[1621, 4, 4, 0], [33, 1, 5, 0], [133, 2, 5, 0], [533, 3, 5, 0], [2133, 4, 5, 0],
[41, 1, 6, 0], [165, 2, 6, 0], [661, 3, 6, 0], [2645, 4, 6, 0], [49, 1, 7, 0],
[197, 2, 7, 0], [789, 3, 7, 0], [3157, 4, 7, 0], [57, 1, 8, 0], [229, 2, 8, 0],
[917, 3, 8, 0], [3669, 4, 8, 0], [65, 1, 9, 0], [261, 2, 9, 0], [1045, 3, 9, 0],
[4181, 4, 9, 0], [73, 1, 10, 0], [293, 2, 10, 0], [1173, 3, 10, 0],
[4693, 4, 10, 0], [81, 1, 11, 0], [325, 2, 11, 0], [1301, 3, 11, 0], …
上のような [奇数, s, t, (eタイプなら 0 or oタイプなら 1)] のようなリストを適当な数(ここでは2桁の奇数が1までの計算で通る奇数をすべて参照できるだけの最小のsとtの値をセットしました)計算した後に、奇数の昇順に並び替えします。
このリストから、最初に入力された奇数を検索してs,tの値を取得し、そのs,tを一般項に代入して、eタイプの奇数か、oタイプの奇数かを判定します。eタイプであれば、6t-5で次の奇数を求め、oタイプであれば、6t-1で次の奇数を求めます。
この計算を奇数が1になるまで繰り返し、奇数の遷移をリストにして出力します。
eタイプの奇数か、oタイプの奇数かの値(0 or 1)をリストに含めていますが、このフラグは計算に使っていないので、なくてもいいデータです。今回必要ないですが、s,t,フラグの3つの組み合わせでユニークとなり、重要な値なのでフラグもデータに入れました
まとめ
このコードは、2桁の奇数のコラッツ計算の答え合わせ(手計算にもコード計算にも!)にどうぞご利用ください
・・・ということで、こっそり言いますが
ここで駆使した、下記のコラッツ一般項は正しいと思われます

最後までお読みいただき、ありがとうございました!