C言語で書いてみました

過去の情報処理技術者試験の出題をもとにして、Cのソースを起こしてみました。

■ 曜日計算(平成13年春期午後問5)

#include <stdio.h>

/* 基本情報 平成13年春期午後問5 */
/* 日付を与えて曜日を求める副プログラム */
#define E1  -1
#define E2  -2
#define E3  -3
#define leap_year(y) ((y)%4==0 && (y)%100!=0 || (y)%400==0)

const char *table[] = { "日","月","火","水","木","金","土" };

int day_of_week(int y, int m, int d)
{
    if (1900>y || y>2299 || 1>m || m>12 || 1>d || d>31) return E1;
    if (d==31 && (m==2 || m==4 || m==6 || m==9 || m==11)) return E2;
    if (d==30 && m==2) return E2;
    if (m==2 && d==29 && !leap_year(y)) return E3;
    /* ツェラーの公式 */
    if (m < 3) { y--; m += 12; }
    return ((y+(y/4)-(y/100)+(y/400)+((13*m+8)/5)+d)%7);
}

int main()
{
    int y, m, d, r, i, size;
    /* 境界値テストデータ */
    char *test[] = {
        "1899,12,31","1900,01,01","2299,12,31","2300,01,01",
        "2001,00,01","2001,01,01","2001,12,01","2001,13,01",
        "2001,01,00","2001,01,01","2001,01,31","2001,01,32",
        "2001,02,28","2001,02,30","2001,02,31","2001,03,31",
        "2001,04,30","2001,04,31","2001,05,31","2001,06,30",
        "2001,06,31","2001,07,31","2001,08,31","2001,09,30",
        "2001,09,31","2001,10,31","2001,11,30","2001,11,31",
        "2001,12,31",
        "1996,02,29","2000,02,29","2001,02,29","2100,02,29",
    };
    size = sizeof(test) / sizeof(test[0]);
    for (i = 0; i < size; i++) {
        sscanf(test[i], "%d,%d,%d", &y, &m, &d);
        r = day_of_week(y, m, d);
        if (r == E1)
            printf("(%04d,%02d,%02d;E1)", y, m, d);
        else if (r == E2)
            printf("(%04d,%02d,%02d;E2)", y, m, d);
        else if (r == E3)
            printf("(%04d,%02d,%02d;E3)", y, m, d);
        else
            printf("(%04d,%02d,%02d;%s)", y, m, d, table[r]);
        if (i % 4 == 3) putchar('\n'); else putchar(',');
    }

    /*
        与えられた年(西暦2000年以降とする)の
        体育の日(10月の第2月曜日)の日付を求める
    */
    printf("\n*** 体育の日の日付を求める***\n");
    printf("年を入力:"); scanf("%d", &y);
    m = 10; d = 0;
    while (1) {
        d++;
        r = day_of_week(y, m, d);
        if (r == 1) {
            d += 7;
            printf("(%04d,%02d,%02d;%s)\n", y, m, d, table[r]);
            break;
        } else if (r == E1) {
            printf("(%04d,%02d,%02d;E1)\n", y, m, d);
            break;
        }
    }

    return 0;
}