0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで一般項によりコラッツ奇数遷移を出力する方法

Last updated at Posted at 2025-04-02

コラッツ演算しないでコラッツ一般項を使って計算する

実行結果は、下のように奇数のみの演算結果を出力します。
でも、3かけて1を足したり、2で割ったり…はしていません。
した方が早いですけれどね:sweat_smile:
一般項を用いて、ひたすら計算しました(させました)。
これは、一般項が合っていますよ~という答え合わせになりますね:sparkles::sparkles:

実行結果
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]
colla_cal
#--------------------------------------------------------------
#    一般項により奇数を計算し、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桁の奇数のコラッツ計算の答え合わせ(手計算にもコード計算にも!)にどうぞご利用ください

・・・ということで、こっそり言います:joy:
ここで駆使した、下記のコラッツ一般項は正しいと思われます:raised_hand:

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

0
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?