#==========
Julia の修行をするときに,いろいろなプログラムを書き換えるのは有効な方法だ。
以下のプログラムを Julia に翻訳してみる。
Collatzの問題
https://oku.edu.mie-u.ac.jp/~okumura/python/collatz.html
ファイル名: collatz.jl 関数名: collatz, collatzmax
翻訳するときに書いたメモ
いきなり規模を大きくすると火傷することがあるよ。
==========#
# #= ... =# は,複数行の注釈 (C++ などの /* ... */ に相当)
#=
def collatz(n):
print(n, end="")
while (n > 1):
if (n % 2 == 0):
n = n // 2
else:
n = 3 * n + 1
print(" →", n, end="")
print()
n = int(input('正の整数を入力してください: '))
collatz(n)
=#
function collatz(n) # 末尾コロン不要
print(n) # 出力末尾改行なしの出力(出力末尾改行ありは println())
while n > 1 # 条件式をくるくるカッコ対,末尾コロン不要
if n % 2 == 0 # 末尾コロン不要
n = n ÷ 2 # 整数除算
else # 末尾コロン不要
n = 3n + 1 # 定数*変数の演算子は省略可
end # if を閉じる
print(" → $n") # 文字列中の $変数名 は変数の値で置換される
end # while を閉じる
println() # 何も出力せず改行のみ
end # function 定義の終わり
print("正の整数を入力してください: ") # プロンプト機能は特にない
n = parse(Int, readline()) # 文字列として入力し,整数にパース
collatz(n) # 関数呼び出し
#=====
def collatz_max(n):
nmax = n
while (n > 1):
if (n % 2 == 0):
n = n // 2
else:
n = 3 * n + 1
if n > nmax:
nmax = n
return nmax
mmax = 0
for n in range(10000):
m = collatz(n)
if m > mmax:
print(n, m)
mmax = m
=====#
function collatzmax(n) # Julia では 変数名,関数名に _ の使用は非推奨
nmax = n
while n > 1
if n % 2 == 0
n = n ÷ 2
else
n = 3n + 1
n > nmax && (nmax = n) # Perl なんかにあるやつ
end
end
return nmax
end
mmax = 0
for n = 0:9999 # Python の range(10000) は 0:9999
m = collatzmax(n)
if m > mmax
println(n, " ", m) # Julia では,フィールドの区切り文字は空
mmax = m
end
end # for も end で閉じる
図を描く Python プログラムは提示されていないが,
図を描くために少し追加
results = []
mmax = 0
limit = 1e8
for n = 1:limit
m = collatzmax(n)
if m > mmax
println(n, " ", m) # Julia では,フィールドの区切り文字は空
mmax = m
append!(results, (n, m))
end
end # for も end で閉じる
collatzmax を若干修正する。
途中で n より小さい値になったら,収束することがわかるの(すでにチェック済みなので)で計算打ち切りにする。
これを入れないと死ぬほど時間が掛かる。
function collatzmax(n) # Julia では 変数名,関数名に _ の使用は非推奨
n0 = n # 後々のために追加
nmax = n
while n > 1
if n % 2 == 0
n = n ÷ 2
else
n = 3n + 1
n > nmax && (nmax = n) # Perl なんかにあるやつ
end
n < n0 && break # n0 より小さくなったら収束するに決まっている!
end
return nmax
end
using Plots
pyplot( scale=:log10, # 両対数軸で描く
grid=false, tick_direction=:out, label="")
plot( results[1:2:end],
results[2:2:end],
markershape=:circle)
plot!( [1, limit],
[1, limit^2],
color=:orange)
※コメント投稿者のブログIDはブログ作成者のみに通知されます