close
 因為昨天 (2009/2/13) 是 13號星期五 .
在吃麻辣鍋時討論到機率應該怎麼算
charto 說 13 號不是星期一就是星期二就是...星期日等七種情況
所以13號星期五大概是 1/7

剛剛就想寫一個程式來驗證這件事情 .
不過是寫得很簡單的程式 , 沒有做什麼多餘的事情
 [想法]
很像在做萬年曆 .

第一步

先存下2009年 每個月 1 號是星期幾 ,
用這個去推算 其他日子是星期幾
如今年 1 月 1 號是 星期四 , 1月22號就會是 (22-1) % 7 + 4 = 4
也是星期四
以此類推 .


第二步

等 2009 年建好以後 , 
就可以用 2009年的日期來推算其他年的日期 .
如果今年的1月1號是星期四 ,
若明年不是閏年 ,
明年的1月1號會是星期五
發現每年之間會存在這樣差一天的規律 ,
閏年的話再另外看他的規則

閏年的判斷是 , 4年一閏 , 逢百不閏 , 四百又閏

如果是閏年 , 原本差一天的規則會因為多了2/29
使得 3月以後的日期變成差兩天 .
所以再小小修改這部份就可以去正確推算各年的日期是星期幾 .

第三步

前置工作做好以後 ,
就可以寫個迴圈去跑 , 把 13號星期五的日期抓出來 ,
以最近十年出現的 13號星期五來分析 ,
最後也可以看 從西元元年至今出現的次數統計



[結果]
2009-2-13
2009-3-13
2009-11-13
2008-6-13
2007-4-13
 
2007-7-13
2006-1-13
2006-10-13
2005-5-13
2004-2-13
 
2004-8-13
2003-6-13
2002-9-13
2002-12-13
2001-4-13
 
2001-7-13
2000-10-13

從 2000 年 到 2009 年 近 10 年間

總共計有 12*10 = 120 次 13號

而出現 13號星期五的次數計有 17

平均 1年出現 1.7次 13號星期五

統計出現的頻率為 17/120 = 0.1417

很接近 1/7 = 0.1428


今年是難得在一年間出現3次13號星期五的一年


另外還計算了近2009年 13號星期五出現的次數

共計有 3456

平均下來一年會出現 (3456/2009) =
1.720258 次 / 年

逢13號為星期五出現的頻率為 0.14335, 也是很接近於 1/7

2009年以後的也可以算 , 只要改一下 code就好了

不過我沒有寫就是了..

我只有以2009年為基礎去反推前面的日期

不過應該可以先算出西元元年的12個月份的一號是星期幾

然後順推其他年份的星期分布情況

code會更精簡 ,

如果要更貼近史實的話 , 可能還要去看之前曆法轉換的史料

不過我沒有想要寫得那麼複雜

至少在近十年內的測試是正確的 , 有拿行事曆google calendar 驗證過


[Code]

#include <stdio.h>

void main(){

  
  int W[12]={4,0,0,3,5,1,3,6,2,4,0,2};
  int month, date;
  int year , week;
  int i , j , c;
  
  year = 1;
  c=0;
  for(i=0;i<12;i++){
   if((W[i]+12)%7==5){
   //printf("2009-%d-13 \n",i+1);  //印出13號星期五的日期
   c++; //計算13號星期五的次數
   }
  }
/* 判斷閏年
 *
 * 四年一閏 逢百不閏 四百又閏
 *
 *
 */    
  for(i=2008;i>=year;i--){
    if((i+1)%400==0){
      for(j=0;j<2;j++){
      W[j] = (W[j]+6)%7;
      }
      for(j=2;j<12;j++){
        W[j] = (W[j]+5)%7;
      }
    }
    else if((i+1)%100==0){
        for(j=0;j<12;j++) W[j]=(W[j]+6)%7;
      }
    else if((i+1)%4==0){
        for(j=0;j<2;j++){
          W[j] = (W[j]+6)%7;
        }
        for(j=2;j<12;j++){
          W[j] = (W[j]+5)%7;
        }
    }
    else{
      if(i%400==0){
        for(j=0;j<2;j++){
          W[j] = (W[j]+5)%7;
        }
        for(j=2;j<12;j++){
          W[j] = (W[j]+6)%7;
        }
      }
      else if(i%100==0){
        for(j=0;j<12;j++) W[j]=(W[j]+6)%7;
      }
      else if(i%4==0){
        for(j=0;j<2;j++){
          W[j] = (W[j]+5)%7;
        }
        for(j=2;j<12;j++){
          W[j] = (W[j]+6)%7;
        }
      }
      else{
      for(j=0;j<12;j++) W[j]=(W[j]+6)%7;
      }
      }

    for(j=0;j<12;j++){
     if((W[j]+12)%7==5){
     c++; //計算13號星期五的次數
     //printf("%d-%d-13 \n",i,j+1);  //印出13號星期五的日期
     }
    }
  }
  /*
  for(i=0;i<12;i++){
    printf("%d ",W[i]);
  }
  printf("\n");
  */ // 印每年每月一號是星期幾
  printf("%d\n",c);
  //printf("%d\n",(W[month-1]+date-1)%7 );

}
arrow
arrow
    全站熱搜

    Rick Lu 發表在 痞客邦 留言(0) 人氣()