Collat​​zの推測をテストするためのこのスクリプトにはどのような問題がありますか?

Collat​​zの推測をテストするためのこのスクリプトにはどのような問題がありますか?

Koracの推測をテストするスクリプトを作成したいと思います。より具体的には、目標は1以外の正の整数を入力できるスクリプトを作成し、Collat​​zアルゴリズムが完了すると1になると予想される最後の数字を印刷することです。

任意の正の整数 n を取ります。 nが偶数の場合、nを2で割ってn / 2を取得します。 nが奇数の場合、nに3を掛けて1を加えて3n + 1になります。このプロセスを無限に繰り返してください。どんな数字から始めても、最終的に1に達すると推測されます。

これが私の試みです -

echo "Enter in a positive integer greater than 1"
read n
let "r=$n%2"
if [ $n -le 1 ]
then
echo "Error: you must enter in a positive integer greater than 1"
exit
fi
while [ $n -ne 1 ]
do
    if [ $r == 0 ]
    then
          let "n=$n/2"
          echo $n
    fi

    if [ $r -ne 0 ]
    then
          let "n=3*$n + 1"
          echo $n
    fi
done

echo $n

2 と入力すると 1 が表示されます。これは望ましい結果です。ただし、3の値を読み取ると、次のような無限ループが発生します。

931947686741790850
2795843060225372551
8387529180676117654
6715843468318801347
1700786331246852426
5102358993740557279
-3139667092487879778
9027742796245912283

.
.
.

など。

私の正確な質問は次のとおりです。私のコードに問題がありますか?大きな数字を印刷する原因は何ですか?

答え1

これ:

let "r=$n%2"
...
while [ $n -ne 1 ]
do
    if [ $r == 0 ]
    ...
done

rループ外で一度だけ割り当てます。

ほとんどのプログラミング言語では、割り当てと同じことは、y = f(x)「現在の値を取得しxf(x)計算を実行してから結果をコピーするy」ことを意味します。これは、「今から永遠までy常に同じでなければならない」という数学的な説明とは異なりますf(x)。コードでは、n次のようには機能しません。値を変更し、ループの複数の反復で異なるように依存します。

rしたがって、最初の数値から得られた値はループ全体にわたって保持され、ループが繰り返されるたびに同じ操作を繰り返すことができます。もちろん、トリプルサークルは膨大な数に達し、あふれ始めます。

解決策は簡単です。割り当てをrループ内に移動して、n変更されるたびに再計算するようにします。

また、引用されていない変数拡張の一般的な問題がありますが、これは問題ではありません。

関連情報