1976年的一天,《華盛頓郵報》于頭版頭條刊登了一條數學新聞,文中叙述了這樣一則故事:70年代中期,美國個所名牌大學校園内,人們都像發瘋一般,日以繼夜廢寝忘食地玩弄一種數學遊戲,這個遊戲十分簡單,任意寫出一個(非零)自然數N,并且按照以下規律進行變換:
- 如果是個奇數,則下一步變成 3N+1
- 如果是個偶數,則下一步變成 N/2
一時間學生、教師、研究員、教授,甚至是一等一的數學大拿、天才都紛紛加入這個看似簡單的數學遊戲,人們取了各種各樣的數字N去檢驗這個算法,最終都無一例外地墜入自然數序列4-2-1,于是就自然萌生出這樣的猜想:對于任意非零自然數N,經上述變換最終都将落入4-2-1序列的宿命。這就是著名的角谷猜想,或稱冰雹猜想。
冰雹猜想最大的魅力,在于其不可預知性,數字N的轉化過程變幻莫測,有些平緩溫和,有些劇烈沉浮,但卻都無一例外地會墜入4-2-1的谷底,這好比是一個數學黑洞,将所有的自然數牢牢吸住。有人把冰雹路徑比喻一個參天大樹,下面的樹根是連理枝4-2-1,而上面的枝枝葉葉則構成了一個奧妙的通路,把一切(非零)自然數統統都覆寫了,這個國小生都看得懂的問題,迄今為止卻沒有任何數學手段和超級計算機可以證明。
冰雹猜想跟蝴蝶效應恰好相悖,蝴蝶效應蘊含的原理是:初始值的極小誤差,會造成結果的巨大不同,而冰雹猜想恰好相反:無論剛開始存在多大的誤差,最後都會自行修複,直到墜入谷底。
C語言程式設計實作:找出程式所能表達的最大整數的範圍内,變換路徑最長的紀錄保持者。
#include<stdio.h>
#include<stdint.h>
#include<math.h>
/*
功 能:對輸入的參數進行冰雹猜想變換,得到1時傳回已經變換的次數,
參 數:num 輸入一個非零自然數
傳回值: 變換得到1時經過的變換次數
*/
long double bingbao(long double num)
{
long double count=0;
while(1)
{
if(fmodl(num,2)==1)//如果是奇數
{
num = 3*num+1;
count++;
}
else if(fmodl(num,2)==0)//如果是偶數
{
num = num/2;
count++;
}
//printf("%Lg\n",num);
if(num == 1)
break;
}
return count;
}
int main()
{
long double num,num_find,count_new=0,count_old=0,len_1=0,len_2=0;
printf("我可以找出你給定範圍内冰雹猜想變換次數最多的自然數\n");
printf("請輸入一個範圍:\n");
printf("起始數:");
scanf("%Lf",&len_1);
printf("末尾數:");
scanf("%Lf",&len_2);
if(len_1>=len_2)
{
printf("輸入錯誤:起始數應該小于末尾數!\n");
return 1;
}
num = len_1;
while(num<len_2)
{
count_new = bingbao(num);
if(count_new>count_old)
{
count_old = count_new;
num_find = num;
}
num++;
}
printf("在你給定的%Lg----%Lg範圍内\n",len_1,len_2);
printf("變換次數最多的是自然數是%Lg\n",num_find);
printf("它經過%Lg次變換後開始得到1\n",count_old);
printf("變換路徑如下:\n");
while(1)
{
printf("%Lg-->",num_find);
if(fmodl(num_find,2)==1)//如果是奇數
{
num_find = 3*num_find+1;
}
else if(fmodl(num_find,2)==0)//如果是偶數
{
num_find = num_find/2;
}
if(num_find == 1)
break;
}
printf("1\n");
return 0;
}
運作結果:linux下運作結果