裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

Julia に翻訳--229 Collatzの問題

2021年05月20日 | ブログラミング

#==========
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)

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« Julia に翻訳--228 2軸グラフ | トップ | Julia に翻訳--230 seaborn ... »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事