[雑談]13日の金曜日の出し方について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KEYONN_

[雑談]13日の金曜日の出し方について

#1

投稿記事 by KEYONN_ » 15年前

13日の金曜日が不吉かどうかは定かではありませんが、
これの計算方法について雑談でもしませんか?

さっそく興味があったので、プログラミングしました。

しかし、少し計算にずれがあったみたいです。
なぜでしょうか!?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int NextYoubi(int youbi)
{
youbi++;
return youbi%7;
}

void Get13thFriday(int Year,int Month,int Day,char youbi[/url])
{
int i,j,k=0;
enum d{SUN,MON,TUE,WED,THU,FRI,SAT};
char y[7][5]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
int DaysTbl[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int day=Day,year=Year,Youbi;
int firstday=0;

for(i=0;i<7;i++)
{
if(strcmp(youbi,y)==0)
{
Youbi=i;
}
}


i=Month;
while(year<2999)
{

if(year%4==0 && i==1)
{
DaysTbl[1]=29;
}
if(DaysTbl<=day)
{
i++;
if(i>11) year++;
DaysTbl[1]=28;
day=1;
Youbi=NextYoubi(Youbi);
i=i%12;
firstday=Youbi;
}

if((day==13 && Youbi==5) && firstday==0)
{
static int cnt=0;
printf("次の13日の金曜日は、%d年%d月%d日です。\n",year,i,day);
cnt++;
if(cnt>5)
break;
}
day++;
Youbi=NextYoubi(Youbi);
}

}

int main()
{
int y,m,d;
char youbi[100];
printf("今日は西暦何年何月何日ですか?->");
scanf("%d,%d,%d",&y,&m,&d);
printf("今日は何曜日ですか?(SUN,MON,TUE,WED,THU,FRI,SAT)で答えて下さい。\n");
scanf("%s",youbi);
Get13thFriday(y,m,d,youbi);

return 0;
}

box

Re:[雑談]13日の金曜日の出し方について

#2

投稿記事 by box » 15年前

> if(year%4==0 && i==1)
> {
> DaysTbl[1]=29;
> }

もし、ここが閏年を求める箇所であるとすると、
「西暦年が4で割り切れる」という条件だけでは不足しています。

KEYONN_

Re:[雑談]13日の金曜日の出し方について

#3

投稿記事 by KEYONN_ » 15年前

ちょっとwikipediaで調べてきます。閏年についてです。

KEYONN_

Re:[雑談]13日の金曜日の出し方について

#4

投稿記事 by KEYONN_ » 15年前

4で割り切れる年は閏年、ただし、
100で割り切れる年は平年(普通の年?)
400で割り切れる年はうるう年です。
と書いてありました。
これは、グレゴリオ暦での計算方法です。

これをif文で表すと

if(year%4==0)
{
if(year%100==0)
return false;

if(year%400==0)
return true;
}
こんな感じですかね。

box

Re:[雑談]13日の金曜日の出し方について

#5

投稿記事 by box » 15年前

return ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? true : false;

質問者さんが書かれたif文は、西暦年が4で割り切れない場合のことを
考慮していないため、不合格。 画像

toyo

Re:[雑談]13日の金曜日の出し方について

#6

投稿記事 by toyo » 15年前

if(year%4==0)
{
if(year%100==0)
return false;

if(year%400==0)
return true;
}
だと下のif文は実行されないですね(400で割り切れる数は必ず100で割り切れる)

組木紙織

Re:[雑談]13日の金曜日の出し方について

#7

投稿記事 by 組木紙織 » 15年前

時間が足りなかったので仕様を合わせるところまではできませんでしたが、13日の金曜日プログラムです。
今晩にでも完成版あげます。


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

enum week{SUN=0,MON=1,TUE=2,WED=3,THU=4,FRI=5,SAT=6};
const int DaysTbl[2][12]={
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};

int checkLeapYear(int y)
{
return ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? 1 : 0;
}

int checkDay(int month, int day,int leapYear)
{
int ret = (month>12||month<1)?0:1;

ret = (ret && DaysTbl[leapYea[/url][month-1]>=day && day>=1)?1:0;
return ret;
}
int Getdays(int month,int day,int leapYear)//うるう年なら1
{
int ret =0;
int i;

if(!checkDay(month,day,leapYear)) return 0;
for(i=1;i<month;++i)
{
ret+=DaysTbl[leapYea[/url][i-1];
}
ret +=day;
return ret;
}
int getWeek(int days,int firstdayWeek)
{
return (days+firstdayWeek-1)%7;
}

void printAnswer(int month)
{
printf("%d月13日は13日の金曜日です\n",month);
}
void Get13thFriday(int firstdayWeek,int leapYear)
{
int i;
for(i=1;i<13;i++){
if(getWeek(Getdays(i,13,leapYear),firstdayWeek)==FRI)printAnswer(i);
}
}

int main()
{
Get13thFriday(FRI,0);
}

へろりくしょん

Re:[雑談]13日の金曜日の出し方について

#8

投稿記事 by へろりくしょん » 15年前

スレ主さんの趣旨とちがったら、ごめんなさい。
曜日を求めるなら、ツェラーの公式を使えば簡単ですよ。

以下のプログラムは1583年~2999年までの13日の金曜日がいつかを列挙します。
#include<stdio.h> 

int getWeek(int y, int m, int d)
{
    if(m < 3) y--, m += 12;

    return (y + y / 4 - y / 100 + y / 400 + (13 * m + 8) / 5 + d) % 7;
}

int main()
{
    int year, month;

    for(year = 1583; year < 3000; year++){
        for(month = 0; month < 12; month++){
            if(getWeek(year, month + 1, 13) != 5) continue;
            printf("%d年 %2d月 13日(金)\n", year, month + 1);
        }
    }

    return 0;
}
私にしては珍しく動作確認済みです。

KEYONN_

Re:[雑談]13日の金曜日の出し方について

#9

投稿記事 by KEYONN_ » 15年前

ツェラーの公式を使って、(wikipediaで調べました。)書き直してみました。
でも、最後がずれてます。
追記:ずれてませんでした。単なる年数の確認間違えでした。

#include<stdio.h>

int Tbl[12]={13,14,3,4,5,6,7,8,9,10,11,12};

int ZellersCongruence(int HighYear,int LowYear,int Month,int Day)
{
int h,q=Day,m=Month,K=LowYear,J=HighYear;

//K:年の2桁、m:月、q:日、h:曜日
h=(q+(((m+1)*26)/10)+K+(K/4)+(J/4)-2*J)%7;

return h;
}

int main(void)
{
int i,j,k,i1,i2;
//
//printf("%d\n",2369/100%100);

for(i=2010;i<2999;i++)
{
for(j=0;j<12;j++)
{
int tmp;
if(j==0 || j==1) {
i1=(i-1)/100%100;
i2=(i-1)%100;
}
else{
i1=i/100%100;
i2=i%100;
}
if(6==ZellersCongruence(i1,i2,Tbl[j],13))
{
static int cnt=0;
printf("次の13日の金曜日は、%d年%d月%d日です。\n",i,j+1,13);
cnt++;
if(cnt>5)
return 0;
}
}
}

return 0;
} 画像

閉鎖

“C言語何でも質問掲示板” へ戻る