どうも,Hiro(@hiroloquy)です.
この記事では,数論の未解決問題の1つである「コラッツ予想(Collatz Conjecture)」が本当かどうか,プログラムを組んで調べてみようと思います.
またプログラムを組む際に,数学関数やデータの可視化に便利なgnuplotで作ろうと思います.
(gnuplotのホームページはこちら)
gnuplotは通常,グラフの可視化ツールとして使われることが多いですが,C言語のprintf()と同等の関数print()を使えば計算結果をターミナル上で表示させることが可能です
そこで今回はコラッツ予想をgnuplotで組んで遊んでみようと思います!
コラッツ予想とは?
以前,ヨビノリ(@Yobinori)のYouTubeでコラッツ予想に関する動画を観ました.
コラッツ予想とは自然数に関する未解決問題です.
計算は足し算,掛け算,割り算の3つしか使わず,四則演算しか使いません!
とてもシンプルなのに,ローター・コラッツが提示した1937年から未だに証明されていないってなんかワクワクしますね笑
そんなワクワクするこの予想の内容は以下のとおりです(詳しく知りたい方は動画をご覧ください)
ある自然数$N$を用意し
- $N$が偶数の場合:$N$を$2$で割る
- $N$が奇数の場合:$N$を$3$倍して$1$足す
の操作を繰り返すと,どんな$N$を選んでも$1$に到達する
例えば,$N=5$のとき
$$ 5 (\mbox{奇数}) \rightarrow 16 (\mbox{偶数}) \rightarrow 8 (\mbox{偶数}) \rightarrow 4 (\mbox{偶数})\rightarrow 2 (\mbox{偶数}) \rightarrow 1 $$
となり,確かに$1$に到達することがわかります.本当にシンプル…
上の例のように$N=5$であれば手計算でコラッツ予想を確認できますが,もっと桁数の多い$N$ではどうでしょうか?
手計算では大変ですよね…
そこで,任意の自然数$N$で調べられるように,冒頭でも書きましたがgnuplotを使ってプログラムを組んでみようと思います.
gnuplotによるコラッツ予想のプログラム
gnuplotで作成したコラッツ予想のプログラム(スクリプト,pltファイル)は以下のとおりです.
使っている関数の簡単な説明はこちらです.
print n
引数n
をターミナル上に表示する.文字列ならprint "文字列"
pause(1)
(本来はpause 1
ですがどっちも一緒)
1秒間待つ.「改行キーが押されるまで待つ」をするならpause -1
.
ちなみに,pause 0
とprint
は一緒.(n%2==0) ? (n/2) : (3*n+1)
これは三項演算子(条件?値1:値2
)です.条件
が真の場合は値1
を,偽であれば値2
を返します.if else
のみで構成されるint型関数と一緒.
コラッツ予想の要である偶奇判定はif else
を使って
if(n%2==0){
n = n%2
} else {
n = 3*n+1
}
とも書けますが,今回はgnuplotに実装されている三項演算子を使って1行にまとめました.
僕はgnuplotで三項演算子に慣れたので大丈夫ですが,「三項演算子 可読性」でGoogle検索すると,三項演算子を使って書くことについて様々な意見がありますね…
ちなみに,このコードではグラフやアニメーションといった可視化を使っていないので,gnuplotの良さを全く活かせていません笑
n
の値を更新しつつ,グラフにプロットすればリアルタイムに値の変動を見ることができるので,gnuplotの良さを活かせそうです.
(可視化はやってみたいので今後やってみます…)
プログラムの実行結果
ターミナル上での実行結果の動画をTwitterにアップしています.動画では$N=27$の場合を調べています.
このときの実行環境の詳細はこんな感じです.
- gnuplot version 5.2 patchlevel 8
- Atom 1.49.0(エディタ)
- script 3.26.0 / PlatformIO IDE Terminal 2.10.0
YouTubeではたくみさんが$N=27$の場合を手計算で調べていましたが,やはりプログラムを組むとすぐに終わります
pause(1)で表示間隔を1秒にして途中経過を眺められるように
— Hiro (@Sm_pgmf) July 22, 2020
偶数が連続すると気持ちいい pic.twitter.com/cl6TgL3XLH
偶数が連続していくと気持ちいいですが,途中で奇数になって増えるともどかしくなります…
$2$の累乗(今回は$16=2^4$)になると一気に消えるので爽快です
すぐに結果を知りたければpause(1)
を消してもらって大丈夫です.
また,pause
の引数を変えれば計算結果の表示速度をコントロールできるので,
フラッシュ暗算みたいな感じでコラッツ予想を楽しめます.
お試しあれ!
コメント