寝癖頭の解法

学習中の覚え書きを投稿、更新していきます。

C++によるコラッツ数列の計算

前回に書いたコラッツの問題(予想)についての話の続きです。
neguse-atama.hatenablog.com
Wikipediaの『コラッツの問題』の中に、「コラッツの数列を計算するプログラミング例」として、擬似コードによるプログラミング例があったので、それを参考にして、とりあえずC++で実装してみました。
ちな、3分ぐらいで。

コラッツの問題は、「任意の正の整数 n をとり、
n が偶数の場合、n を 2 で割る
n が奇数の場合、n に 3 をかけて 1 を足す
という操作を繰り返すと、どうなるか」というものです。
で、「どんな初期値から始めても、有限回の操作のうちに必ず 1 に到達する(そして 1→4→2→1 というループに入る)」という主張が、コラッツの予想です。

このプログラムは、入力された自然数(正の整数)を初期値とした、コラッツ数列を計算できます。
要するに、初期値からスタートして、1 に到達するまでのステップを出力します。

だから、コードとして書けば、こんな感じになります。

C++によるコラッツ数列の計算
/*
Collatz Conjecture in C++
C++によるコラッツ数列の計算
https://neguse-atama.hatenablog.com
*/
#include<bits/stdc++.h>
using namespace std;
vector<int> collatz(int n){
    vector<int> r;
    r.push_back(n);
    while(n!=1){
        if(n%2==0){
            n/=2;
        }else{
            n*=3;
            n+=1;
        }
        r.push_back(n);
    }
    return r;
}
int main(void){
    int n;
    cin>>n;
    vector<int> v=collatz(n);
    int vs=v.size()-0;
    for(int i=0;i<vs;i++){
        cout<<v[i]<<((i==vs-1) ? "\n" : " ");
    }
    return 0;
}

このプログラムは無限サイクルを省くために、1 に到達すると停止するようになっているので、もしもコラッツ予想が正しければ、いかなる正の整数の初期値を与えても停止する、と言うわけです。
つまり1に到達しない初期値を見つけたら、同時に反例を発見した! と言うことになるはずです、たぶん、きっと。
ただし、初期値(入力)の値が大きくなれば大きくなるほど、計算量も増えていくことになるから、あらかじめ実行環境による限界がある(フリーズしちゃうかも?)と考えられます。
なおコンピュータを利用した計算によれば、3 × 2 ^53 = 27,021,597,764,222,976 以下については反例がないことが知られています。

動作の確認については、とりあえずオンライン実行環境のpaiza.IOに通してみてから...
f:id:neguse_atama:20211002193435p:plain

Macのターミナルでも実行しておきました。
f:id:neguse_atama:20211002202630p:plain
はい、大丈夫みたいです。

あと、GitHubにもアップロードしておきました。
github.com