すのものの「いろいろ」(その21)

月の大小が5カ月でくり返すことを使っても Zeller の公式は簡単にならない

ある年の三月が日曜日 (0) から始まるとすると、 翌年の二月までの曜日は次のようになる。

大小
345678 910111212
曜日 035136 240251

よく見ると五カ月のパターンでくり返しているのだ。

大小
34 56 78 910 1112 12
曜日 03 51 36 24 02 51
↓+1 ↓+2
03 51 30 35 13 03

式 5 * (m + 1) / 2 - 2 は、 m = 0, 1, 2, 3, 4 に対して最初の五カ月の曜日 0, 3, 5, 1, 3 (mod 7) を返す。 これを利用すると Zeller の公式を次のように改造できる。

int zeller(int year, int month, int day) {
    month -= 3;
    if (month < 0) {
        year--; month += 12;
    }
    return (year + year / 4 - year / 100 + year / 400 \
              + 5 * (month % 5 + 1) / 2 - month / 5 + day) % 7;
}
しかし、5 で割るのが二回に増えているので、 これでは改悪だ。

2001-01-03 (3) 01:32:50 +0900

TABLE に /TH, /TD, /TR タグを補った。

2004-05-04 (2) 19:57:02 +0900

うるう日はどこに挿入するのが合理的か? 年の終わり? 年の初め?

現行のように2月末日にうるう日をおくのはそれほど合理的とは思えない。 年の最後におくほうが合理的だと思っていたが、 Zeller の公式で 1 月と 2 月を別処理することを思うと、 年の最初におくほうが合理的なのかもしれない。

年によって大みそかの日付が変わるのも年の初めに一日おまけがあるのも どちらも不便だろうけれど。

2001-01-02 (2) 22:33:40 +0900

幼稚園の自由画でカレンダーを描いたことがあるほど、私はカレンダーが好き

幼稚園で好きな絵を描くように言われたとき、 私はカレンダーの絵を描いたことがあるそうだ。 「カレンダーに使えそうな絵」ではなく、 カレンダーに数字が並んでいるのを絵に描いたらしい。 ほかに、「普通の年の次の年は曜日が一つ進むが、うるう年だと二つ進む」 と言って先生を驚かせたこともあったらしい。

2001-01-02 (2) 01:30:30 +0900

「フォーラムかや(榧)」のページには壁紙になりそうなサンプルがたくさん

新聞で URL を見た 「フォーラムかや(榧)」のページには、 壁紙になりそうなサンプルがたくさんおいてある。 ちょっと小さめだが。 千住博氏の作品もあった。 「各大画面」(拡大画面)とか「五十の塔」(五重の塔) とかの“楽しい誤変換”もいっぱい!

2001-01-02 (2) 01:15:08 +0900

「四月八日はお釈迦様のクリスマス」というコピーを考えたことがある

「潅仏会(かんぶつえ)」「花祭(はなまつり)」 などと言うと古くさい感じがするが、 これなら若い人もきてくれるのではないだろうか?

2001-01-02 (2) 01:01:27 +0900

Zeller の公式を紀元 1 年 12 月 24 日からの通算日数を求めるよう“改造”

Zeller の公式を通算日数を求めるように“改造” すると (2000-12-31 (0) 23:18:25 +0900)」 で示した関数は紀元 0 年 3 月 1 日を第 1 日とした通算日数を返す。 この値を 7 で割った余りは曜日に一致しない。 一致させるには、適当な数を足すか引くかすればいいだけだが、 どうせなら何か意味のある日からの通算日数としたかった。 あの時は名案を思いつかなかったが、 きのう床にはいってから 「紀元 1 年はことし 2001 年と同じカレンダーだから月曜から始まる。 平年だから 12 月 31 日も月曜日。 よってその一週間前の 12 月 24 日も月曜日だ!」 と気がついた。 前のプログラムでこの日を調べると 664 日目。 よって、

/*(グレゴリウス暦)1 年 12 月 24 日を第 1 日とした通算日数を返す。*/
/*  7 で割った余りは曜日(0 が日曜、1 が月曜、6 が土曜)に等しい。*/
long zeller(int year, int month, int day) {
    if (month < 3) {
        year--; month+=12;
    }
    return 365L * year + year / 4 - year / 100 + year / 400 \
                            + (153 * month - 457) / 5 + day - 663;
}
とすればいいわけだ。

この関数はイエス・キリストの生誕からの日数を返す、 と(思いたい人は)思ってもいい。 ただし、 「ナザレのイエスの誕生は紀元 1 年ではないらしい」 「ナザレのイエスの誕生日は 12 月 24 日ではないらしい」 「紀元 1 年にはグレゴリウス暦は使われていなかった」 などの意味で仮想的なものであるが。

2001-01-02 (2) 00:56:10 +0900

上のリンクはいまはった。 もとは a href タグをおいていなかった。

2004-05-04 (2) 19:31:34 +0900

西暦の下2ケタだけを表記するなら、きょうは 01-01-01 (1) だったのか……

曜日も 1 だったとは。

2001-01-01 (1) 23:30:56 +0900

Zeller の公式を使わずに配列を参照するようにしたら

下の zeller2() のように。 このほうが速いような気がする。 Zeller の公式のメリットはタイピング量が少なくて済むこと?  データの量も少なくて済むからメモリが少なかった時代にはよかったかも。

#include <stdio.h>
#include <stdlib.h> /* atoi */

int zeller(int year, int month, int day);
int zeller2(int year, int month, int day);

int main(int argc, char* argv[]) {
    printf("%d ", zeller(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])));
    printf("%d\n", zeller2(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])));
    return 0;
}

/* 元の */
int zeller(int year, int month, int day) {
    if (month < 3) {
        year--; month += 12;
    }
    return (year + year / 4 - year / 100 + year / 400 \
                            + (13 * month + 8) / 5 + day) % 7;
}

int zeller2(int year, int month, int day) {
    static const char days[] = { -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };

    if (month < 3) {
        year--;
    }
    return (year + year / 4 - year / 100 + year / 400 + days[month] + day) % 7;
}

2001-01-01 (1) 23:28:10 +0900

Zeller の公式にわざわざ手を入れてバグを引き起こす

400 年でグレゴリウス暦が完全に元に戻ることを使えば下の Zeller2() のようにしてもよいが、別に何ら改良にはなっていない。 Zeller3() は誤りである。 year が 400 の倍数のとき year を 400 で割った余りは 0 となるが、 month が 1 または 2 のときは year から 1 を減ずるので -1 となり、 それを割った結果は処理系依存なのだ。 確か去年のはじめに massangeana 氏が奥村さんのゲストブックに書いておられた、 あるカレンダーソフトの不具合の原因がこれではないかと。

#include <stdio.h>
#include <stdlib.h> /* atoi */

int zeller(int year, int month, int day);
int zeller2(int year, int month, int day);
int zeller3(int year, int month, int day);

int main(int argc, char* argv[]) {
    printf("%d ", zeller(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])));
    printf("%d ", zeller2(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])));
    printf("%d\n", zeller3(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])));
    return 0;
}

/* 元の */
int zeller(int year, int month, int day) {
    if (month < 3) {
        year--; month += 12;
    }
    return (year + year / 4 - year / 100 + year / 400 \
                            + (13 * month + 8) / 5 + day) % 7;
}

/* いじってみたが改良にはなっていない */
int zeller2(int year, int month, int day) {
    if (month < 3) {
        year--; month += 12;
    }
    year %= 400;
    return (year + year / 4 - year / 100 + (13 * month + 8) / 5 + day) % 7;
}

/* 間違い!*/
int zeller3(int year, int month, int day) {
    year %= 400;
    if (month < 3) {
        year--; month += 12;
    }
    return (year + year / 4 - year / 100 + (13 * month + 8) / 5 + day) % 7;
}

2001-01-01 (1) 23:04:04 +0900

NHKの大相撲中継などで使われた「分解写真」が広辞苑第五版に載ってない

ビデオのスロー再生の代わりに使われていたあれ。

2001-01-01 (1) 22:35:42 +0900

クイズ>Zeller の公式に関係があります

           □■
          □□
        □□□
      □□□
     □□
   □□□
 □□□
■□
上の図のように正方形の小部屋が連結しているとする。 このとき、「■」 で示した両端の小部屋にいる二人は目と目を合わせることができるだろうか?  部屋と部屋の間にはしきりなどは何もないが、 部屋の回りには壁があり、光を通さないものとする。

Zeller の公式を自前で導きだしてみる (2001-01-01 (1) 02:19:09 +0900)」 の図形に関する問題を、クイズ仕立てにしてみたもの。 答えは「できる」。 ただし、Zeller の公式のときは境界の等号・不等号の問題があったので全く同じ問題ではない。

2001-01-01 (1) 22:29:08 +0900

上のリンクはいまはった。 もとは a href タグをおいていなかった。

2004-05-04 (2) 19:27:49 +0900

続・自分でも賛成しない改暦試案 --- 2月の日数が少ないのを直すとしたら

前に 1999-07-30 (5) 18:53:55 +0900 づけで書いた案は、 2月は平年は小の月、うるう年には大の月とし、 あとは偶数月を大の月とする、というのだった。

《1月は現在は31日、改暦後は30日。 よって−1となる。 2月は28日から30日の+2だから、 2月が終わった時点で+1。 これを12月まで続けてみると、 「−1、+1、0、+1、0、+1、0、0、0、0、0、0」となり、 2日以上ずれるときがない》 と書いたが、 3月から考え始めれば 「−1、0、−1、0、−1、−1、−1、−1、−1、−1、−2」 となる。

Zeller の公式を自前で導きだしてみる (2001-01-01 (1) 02:19:09 +0900)」 に書いたような、 《横軸に月をとり、 縦軸には各月の日数で 30 日を越える分の前月までの累計》をとったグラフは、 次のようになる。

 |
8|
7|
6|            ・・
5|          ・・・・
4|        ・・・・
3|      ・・・・
2|    ・・・・
1|  ・・・・
 +−−・・−−−−−−−−−−−
O 12345678911111
           01234
これなら“Zeller の公式”を作るのもやさしい。 求める直線の傾きは 1/2 にとれる。

2001-01-01 (1) 20:22:53 +0900

上の2つのリンクはいまはった。 もとは a href タグをおいていなかったのだ。

2004-05-04 (2) 19:26:22 +0900

Zeller の公式を自前で導きだしてみる

Zeller の公式で一番ふしぎなところは (13 * month + 8) / 5 の部分だろう。 ただし、1 月、2 月は前年の 13 月、14 月とみなす。 どうしてこれを考えついたのか、考えてみた。

横軸に月をとり、 縦軸には各月の日数で 30 日を越える分の前月までの累計をとってみると、 下の黒点のようになる。

 |
8|             
7|            ・
6|          ・・・
5|        ・・・・
4|       ・・
3|     ・・・
2|   ・・・・
1|  ・・
 +−−・−−−−−−−−−−−−
O 12345678911111
           01234
この黒点よりも上にあり、 かつこれを上に1だけずらした赤点よりは下にあるような関数を、 なるべく簡単な形で求めたい。 もしも一次関数で求めようとするなら、 「黒点よりは上にあり、赤点よりは下にあるような直線を引け」 ということになる。 (「黒点よりは上」と言ったが、黒点は通ってもよい。赤点は通ってはいけない。)

(もしも答えがあるとわかっていなかったら、 この図形を見た時点で直線をひくことはあきらめてしまうだろう。 だってひけそうにないんだもん(笑)。)

直線を y = ax + b とおいて係数 a, b の満たすべき条件を調べるのだが、 このままでは点が 24 個あるので条件も 24 個ある。 これを少し減らしてからにしたい。

4 月から 9 月までの黒点

          ・
         ・
       ・・
     ・・
を見ると、両端の二点を結ぶ線分は間のどの点よりも上にある。 よって、 ある直線が両端の二点よりも上にあれば、間のどの点よりも上にあることになる。 9 月から 14 月も全く同じ形である。 4 月、9 月、14 月は同一直線上にある。 よって、黒点は 3 月、4 月、14 月の三つだけを考えればよい。 このようにして黒点を減らしたのが次の図である。
 |
8|             
7|            ・
6|          ・・
5|        ・・
4|       
3|     ・・
2|   ・・
1|  ・
 +−−・−−−−−−−−−−−−
O 12345678911111
           01234
同様に、赤点は 3 月、7 月、12 月、14 月の四つだけを考えればよい。
 |
8|             
7|             ・
6|           
5|
4|
3|      
2|
1|  ・
 +−−・−−−−−−−−−−−−
O 12345678911111
           01234
4 月の黒点と 12 月の赤点を結ぶ直線 l は 14 月の赤点よりも下にある。 ある直線 m が 4 月には黒点よりも上(あるいは等しい高さ)にあって 12 月には赤点よりも下にあるなら、 m は 4 月には l よりも上(あるいは等しい高さ)にあり、 12 月には l よりも下にある。 よって、l と m は 4 月と 12 月の間(4 月かもしれない)で交わる。 よって、l と m は 12 月と 14 月の間では交われず、 m は 14 月の赤点よりも下にある。 よって、14 月の赤点は条件からはずしてよろしい。 同様に、4 月の黒点と 7 月の赤点を考えれば 3 月の黒点を、 7 月の赤点と 14 月の黒点を考えれば 3 月の赤点を消すことができる。
 |
8|
7|             ・
6|           
5|
4|
3|      
2|
1|   ・
 +−−−−−−−−−−−−−−−
O 12345678911111
           01234
すると条件式は次の四つになる。
1 <=  4a + b      ... (1)
      7a + b < 3  ... (2)
     12a + b < 6  ... (3)
7 <= 14a + b      ... (4)
(1) を 1 - 4a <= b と、(3) を b < 6 - 12a と変形して組み合わせると 1 - 4a < 6 - 12a となり、これから a < 5/8 を得る。 (2) を b < 3 - 7a と、(4) を 7 - 14a <= b と変形して組み合わせると 7 - 14a < 3 - 7a となり、これから a > 4/7 を得る。 よって 4/7 < a < 5/8 がわかった。

a, b は分母の小さな有理数であることが望ましいが、 上の条件から a の分母が 2, 3, 4 では解なし。 a の分母が 5 とすると a = 3/5 が候補である。 (1)〜(4) から -7/5 <= b < -6/5 が得られるから、 例えば b = -7/5 ととればよい。 つまり、y = (3/5)x - 7/5 が答えの一つだ。

元へ戻れば day = 30 * (month - 3) + (3 * month - 7) / 5 であり、この右辺は (153 * month - 457) / 5 となる。 これは、 「Zeller の公式を通算日数を求めるように“改造” すると (2000-12-31 (0) 23:18:25 +0900)」 で求めた month の項と同じである。

a の分母が 6, 7, 8 では解なし。

すこしとばして、分母が 2 のベキで見つからないかと a の分母を 16 としてみてもやはり見つからない。 このへんでやめよう。

2001-01-01 (1) 02:19:09 +0900

付) 最後の図に混入していた余分な“タグ”を削除した。 それについては 「ブラウザによっては余分な </FONT> で等幅フォントが終わってしまう (2001-02-17 (6) 01:01:35 +0900)」 を参照。

2001-02-17 (6) 01:07:26 +0900

上の2つのリンクはいまはった。 もとは a href タグをおいていなかったのだ。

2004-05-04 (2) 19:19:01 +0900

30.5 日を越える分の前月までの累計をグラフにすると

  |
 3|
  |             
 2|        ・ ・ ・
  |   ・ ・ ・ ・ ・ ・
 1|  ・ ・ ・ ・ ・ ・
  |   ・ ・ ・ ・ ・
 0+−−・−・−・−−−−−−−−
   12345678911111
            01234
となる。 このグラフだと、傾き 1/10 の直線が引けることが(割と)すぐ見える。 元に戻すため 30.5 を加えれば傾き 30.6 であり、 これは上の 153/5 に等しい。

2008-03-10 (1) 03:00:09 +0900

最初に書いた部分(=加筆でない部分)の最後にあげたグラフでは、 ほとんど一直線上に四つの点が並んでいる。 ここで点の位置をよく見ると、 黒で示した二点を結ぶ直線が求める直線であることがわかる。 そう考えれば、条件式を考える必要はないのだった。 (より簡単な係数で見つからないだろうかと考えるなら必要だが。)

2008-03-13 (4) 01:51:19 +0900

うるう秒が頻繁になると「その時計は使えませんよ」という詐欺が出てくる?

電波時計でデジタル表示なら、 前もってうるう秒を認識しておいて 8:59:60 を表示することもできよう。 そういうのを売りつけにくるとか。

2000-12-31 (0) 23:51:10 +0900

「グレゴリウス暦の紀元 1 年 3 月 1 日」などというとなぜおかしいか?

グレゴリウス暦が導入されたのはずっとあとのことだが、 その暦法を過去にも延長したと考えれば、 「紀元前 626 年」と同様、おかしくないのではないか。 とはいうもののやはり何か違う。 「そのときを記述する別の暦があるかどうか」 「『年だけ』と『日付』の違い」 などいろいろ考えられよう。

2000-12-31 (0) 23:48:00 +0900

時差を 24 時間“進める”と、その1日はどこへいってしまうのか?

日付変更線の近くのどこかの地域が、 何年か前に時差を 24 時間“増やした”ことがあった。 正確には覚えていないが、 例えば「UTC から 11 時間遅れ」を「UTC から 13 時間進んでいる」 に改めるように変更したのである。 こうすることでどこよりも早く 2000 年だか二十一世紀だかを迎えるようにして観光の目玉に、 というのだったような気がする。 時計の針は動かさなくていいから楽だが、日付を一日進めることになる。 給料や家賃の計算とかはどうしたのだろうか?

「もう、二十一世紀にはいった地域もあるんだな」と思ったら思い出した。

2000-12-31 (0) 23:31:35 +0900

Zeller の公式を通算日数を求めるように“改造”すると

私は Zeller の公式を奥村晴彦氏の 「C言語による最新アルゴリズム事典」(技術評論社) で知ったが、 それを元に書いた関数は次のようになっている。 (C言語の約束により、 正の整数どうしの割り算は小数点未満切り捨てである。)

int zeller(int year, int month, int day) {
    if (month < 3) {
        year--; month += 12;
    }
    return (year + year / 4 - year / 100 + year / 400 \
                            + (13 * month + 8) / 5 + day) % 7;
}
これをちょっと手直しすれば、 ある日からの通算日数を返す関数に“改造”することができそうである。 (ここで“改造”に引用符をつけたのは、 もしかしたら、 元々 Zeller の公式はそういうものだったかもしれないからである。)

ちょっと考えて、

long zeller(int year, int month, int day) {
    if (month < 3) {
        year--; month+=12;
    }
    return 365L * year + year / 4 - year / 100 + year / 400 \
                            + (153 * month - 457) / 5 + day;
}
でいいらしいとわかった。 どう考えたかを以下に記しておく。

まず、 month と day を固定しておいて year を 1 だけ増やすと、 返る値はその年の日数だけ増加する。 1 月、2 月は前年の 13 月、14 月として扱っていることを思い出すと、 通算日数もそれだけ増加する。よって正しい。 day もこれで問題ない。

問題は month に関する項だが、 まずは元の (13 * month + 8) / 5 に 7 の倍数である 28 * (month - 3) を加えて (153 * month - 412) / 5 としてみる。 これに month がとりうる 12 通りの値を代入して計算すると次の表のようになる。 (通算日数を書くときのくせで3ケタにしている。八進表記ではない。)
month 345678 91011121314
009040070101131162 193223254284315346
この値は、「その月の 0 日の、3 月 1 日からの通算日数 + 9」に一致している。 このままでもよいのだが、 9 を引いて (153 * month - 457) / 5 とすれば 3 月 1 日には month と day の項の和は 1 となる。

よって、紀元 0 年 3 月 1 日が第 1 日目である。 これより前の日付は紀元 -1 年の扱いなので year が負になる。 C言語は負の整数の割り算については処理系依存の部分があるので、 これより前は year に前もって正の数を足しておくなどしないと扱えない。 (そもそも、そんな昔にグレゴリウス暦が使われていたはずがない!)

なお、上の関数が返す値を 7 で割った余りは曜日に一致しない。 一致させたければ 2 を足す必要がある。

2000-12-31 (0) 23:18:25 +0900

TABLE に /TH, /TD, /TR タグを補った。

2004-05-04 (2) 19:13:58 +0900

酒をつければ、「未成年者には売らない」という本の売り方もできるのでは?

ちょっと前の新聞に、 未成年者に酒を売らないように法律を厳しくする、 というような話が出ていた。 本屋で売っているものの中にも成人向きと思われるものがあろうが、 製作者側で「これは成人のみに売ってくれ」 といって出版することはむずかしいだろう。 本屋では年齢をチェックする習慣がないからだ。

そこで思いついたのだが、 本に申しわけ程度のお酒をつけて、酒屋で売ることはできないだろうか?  よく、スーパーのお菓子売り場で数粒のガムがついたおもちゃを売っているが、 それと似た発想である。

2000-12-31 (0) 02:42:18 +0900

(international) week number で第 53 週まである年はどのように分布する?

グレゴリウス暦では、400 年でカレンダーは完全に元に戻る。 平年は 52 週と 1 日であり、400 年間に 97 日のうるう日がはいるので (400+97)/7 = 497/7 = 71 年だけ、第 53 週まである年があるわけだ。 そのような週はどのように分布するのだろう?

C言語>(international) week number を返す関数 (2000-12-31 (0) 01:29:00 +0900)」 における考察によれば、 第 53 週があるのは 木曜日から始まる年と水曜日から始まるうるう年である。 それに基づいて 1601 年から 2000 年までを調べ、表にしてみた。 背景が緑なのはうるう年であり、 曜日は 1 月 1 日の曜日である。 それが大カッコにはいった赤字で書かれている年は第 53 週がある。

1601
1602
1603
1604
[木]
1605
1606
1607
1608
1609
[木]
1610
1611
1612
1613
1614
1615
[木]
1616
1617
1618
1619
1620
[水]
1621
1622
1623
1624
1625
1626
[木]
1627
1628
1629
1630
1631
1632
[木]
1633
1634
1635
1636
1637
[木]
1638
1639
1640
1641
1642
1643
[木]
1644
1645
1646
1647
1648
[水]
1649
1650
1651
1652
1653
1654
[木]
1655
1656
1657
1658
1659
1660
[木]
1661
1662
1663
1664
1665
[木]
1666
1667
1668
1669
1670
1671
[木]
1672
1673
1674
1675
1676
[水]
1677
1678
1679
1680
1681
1682
[木]
1683
1684
1685
1686
1687
1688
[木]
1689
1690
1691
1692
1693
[木]
1694
1695
1696
1697
1698
1699
[木]
1700
1701
1702
1703
1704
1705
[木]
1706
1707
1708
1709
1710
1711
[木]
1712
1713
1714
1715
1716
[水]
1717
1718
1719
1720
1721
1722
[木]
1723
1724
1725
1726
1727
1728
[木]
1729
1730
1731
1732
1733
[木]
1734
1735
1736
1737
1738
1739
[木]
1740
1741
1742
1743
1744
[水]
1745
1746
1747
1748
1749
1750
[木]
1751
1752
1753
1754
1755
1756
[木]
1757
1758
1759
1760
1761
[木]
1762
1763
1764
1765
1766
1767
[木]
1768
1769
1770
1771
1772
[水]
1773
1774
1775
1776
1777
1778
[木]
1779
1780
1781
1782
1783
1784
[木]
1785
1786
1787
1788
1789
[木]
1790
1791
1792
1793
1794
1795
[木]
1796
1797
1798
1799
1800
1801
[木]
1802
1803
1804
1805
1806
1807
[木]
1808
1809
1810
1811
1812
[水]
1813
1814
1815
1816
1817
1818
[木]
1819
1820
1821
1822
1823
1824
[木]
1825
1826
1827
1828
1829
[木]
1830
1831
1832
1833
1834
1835
[木]
1836
1837
1838
1839
1840
[水]
1841
1842
1843
1844
1845
1846
[木]
1847
1848
1849
1850
1851
1852
[木]
1853
1854
1855
1856
1857
[木]
1858
1859
1860
1861
1862
1863
[木]
1864
1865
1866
1867
1868
[水]
1869
1870
1871
1872
1873
1874
[木]
1875
1876
1877
1878
1879
1880
[木]
1881
1882
1883
1884
1885
[木]
1886
1887
1888
1889
1890
1891
[木]
1892
1893
1894
1895
1896
[水]
1897
1898
1899
1900
1901
1902
1903
[木]
1904
1905
1906
1907
1908
[水]
1909
1910
1911
1912
1913
1914
[木]
1915
1916
1917
1918
1919
1920
[木]
1921
1922
1923
1924
1925
[木]
1926
1927
1928
1929
1930
1931
[木]
1932
1933
1934
1935
1936
[水]
1937
1938
1939
1940
1941
1942
[木]
1943
1944
1945
1946
1947
1948
[木]
1949
1950
1951
1952
1953
[木]
1954
1955
1956
1957
1958
1959
[木]
1960
1961
1962
1963
1964
[水]
1965
1966
1967
1968
1969
1970
[木]
1971
1972
1973
1974
1975
1976
[木]
1977
1978
1979
1980
1981
[木]
1982
1983
1984
1985
1986
1987
[木]
1988
1989
1990
1991
1992
[水]
1993
1994
1995
1996
1997
1998
[木]
1999
2000

1700 年、1800 年、1900 年の前後を除き、 28 年でカレンダーは元に戻る。 例えば 1903 年が第 53 週まである年だが、 そこから始めてそのような年をあげてゆくと 1903 年、1908 年、1914 年、1920 年、1925 年、1931 年であり、 間隔は 5 年、6 年、6 年、5 年、6 年となっている。 例外の 1700 年、1800 年、1900 年の前後では、 1900 年のところだけ間隔が 7 年となっている。 一年に 1 日は曜日が進むので、これ以上長い間隔はありえないが、 その 7 年が実際に起こっていることがわかる。

表を作るには、以下のプログラムを用いた。

#include <stdio.h>

#define isleap(X) (!((X)%4) && (((X)%100) || !((X)%400)))   /* うるう年? */

int zeller(int year, int month, int day);
int week53(int year);

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

main() {
    int i, j;

    printf("<TABLE border>\n");
    for (i=1600; i<2000; i+=20) {
        printf("<TR>\n");
        for (j=1; j<=20; j++) {
            int year = i+j;
            int leap = isleap(year);

            printf("<TD align=\"center\"%s>", 
                    leap ? " bgcolor=\"#CCFFCC\"" : "");
            printf("%d<BR>", year);
            if (week53(year)) {
                printf("<FONT COLOR=\"red\">[%s]</FONT>",
                                    wday[zeller(year, 1, 1)]);
            } else {
                printf("%s", wday[zeller(year, 1, 1)]);
            }
            printf("\n");
        }
    }
    printf("</TABLE>\n");
    return 0;
}

/* 奥村晴彦氏の「C言語による最新アルゴリズム事典」(技術評論社)から引用 */
int zeller(int year, int month, int day) {
    if (month < 3) {
        year--; month += 12;
    }
    return (year + year / 4 - year / 100 + year / 400 \
                            + (13 * month + 8) / 5 + day) % 7;
} /* zeller() */

/* 第 53 週があれば 1, なければ 0. */
int week53(int year) {
    switch(zeller(year, 1, 1)) {
        case 1: case 2: case 5: case 6: case 0: return 0;
        case 3: return isleap(year);
        case 4: return 1;
    }
} /* week53 */

しかし、400 年といえどもこうやって表にしてみると「たったこれだけ?」 って感じだ。

2000-12-31 (0) 01:54:40 +0900

上のリンクはいまはった。 もとは a href タグをおいていなかった。

2004-05-04 (2) 20:08:47 +0900

C言語>(international) week number を返す関数

ここでは月曜日から次の日曜日までを“週”と言うことにする。 一つの年を固定する。 その年に属する日を4日以上含む週を時間の流れに沿って 1 番目、2 番目、……と並べたとき、 その番号をその週の (international) week number と呼ぶ。 グレゴリウス暦のもとではこれできちんとした定義になっており、 どんな年でも week number の最大は 52 または 53 である。

1 月 1 日の曜日によって7通りに場合分けすると、 1 月 1 日付近の week number は以下のようになる。

case a)   1 |  1  2  3  4  5  6  7

case b)   1 | 31  1  2  3  4  5  6

case c)   1 | 30 31  1  2  3  4  5

case d)   1 | 29 30 31  1  2  3  4

case e)  53 | 28 29 30 31  1  2  3
          1 |  4  5  6  7  8  9 10

case f)  5? | 27 28 29 30 31  1  2
          1 |  3  4  5  6  7  8  9

case g)  52 | 26 27 28 29 30 31  1
          1 |  2  3  4  5  6  7  8
よって、week number が 1 である週とは、1 月 4 日を含む週、 と考えてもよい。 日本ではこの日が“御用始め”なので、このほうが覚えやすいかもしれない。

また、上で「53」「5?」「52」と書いたところが実際そうなることは、 以下のように前年の 1 月 1 日付近を考えればわかる。 それぞれの case で 1) は前年が平年、 2) はうるう年の場合である。 (「?」は前年が平年かうるう年かによって「2」または「3」となる。)

case e-1)   1 |           1  2  3  4
                          :
           53 | 28 29 30 31  1  2  3
            1 |  4  5  6  7  8  9 10

case e-2)   1 |        1  2  3  4  5
                          :
           53 | 28 29 30 31  1  2  3
            1 |  4  5  6  7  8  9 10

case f-1)     |              1  2  3
            1 |  4  5  6  7  8  9 10
                          :
           52 | 27 28 29 30 31  1  2
            1 |  3  4  5  6  7  8  9

case f-2)   1 |           1  2  3  4
            2 |  5  6  7  8  9 10 11
                          :
           53 | 27 28 29 30 31  1  2
            1 |  3  4  5  6  7  8  9

case g-1)     |                 1  2
            1 |  3  4  5  6  7  8  9
                          :
           52 | 26 27 28 29 30 31  1
            1 |  2  3  4  5  6  7  8

case g-2)     |              1  2  3
            1 |  4  5  6  7  8  9 10
                          :
           52 | 26 27 28 29 30 31  1
            1 |  2  3  4  5  6  7  8

struct tm 型へのポインタを渡すと week number を返す関数を書いてみた。

【その1】 ANSI C のライブラリ関数 strftime() は、 %W を 「その年の week number(最初の月曜日を week 1 の最初の日とする)」 に置き換える。 これを仮に Monday week number と呼ぶと、 これはいま論じている week number とは異なるが、 ある時刻とその時刻を含む年の 1 月 4 日について Monday week number を求めれば、その差から我々の week number を求めることができる。 ただし、 それが 0 になったら上の e) f) g) の case であるから、 前年の 12 月 31 日の week number を返す。 53 になったときは、 もしかしたら翌年の第 1 週なのかも知れない。 上の分類をみれば、「日」から「曜」(月曜が 1, 土曜が 6)を引いて 28 以上かどうかをチェックすればよいことがわかる。

#include <stdio.h>
#include <stdlib.h> /* atoi */
#include <time.h>   /* struct tm */

int weeknumber(const struct tm* tp);

int main(int argc, char* argv[]) {
    int year;
    char str[80];
    struct tm tm;

    if (argc != 2) {
        puts("年(西暦、4ケタ)をつけて動かしてください.");
        puts("その年のすべての日の week number を出力します.");
        return 1;
    }
    year = atoi(argv[1]) - 1900;
    tm.tm_year = year; tm.tm_mon = 0; tm.tm_mday = 1;
    tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0;       /* 1月1日にセット */
    while (mktime(&tm), tm.tm_year == year) {
        strftime(str, 80, "%Y-%m-%d (%w) week number ", &tm);
        printf("%s", str);
        printf("%2d\n", weeknumber(&tm));
        tm.tm_mday++;   /* 翌日に進める */
    }
    return 0;
}

/* (international) week number を返す */
int weeknumber(const struct tm* tp) {
    struct tm tm = *tp;
    int jan4, today, ret;
    char tmp[3];

    strftime(tmp, 3, "%W", &tm);
    today = atoi(tmp);                  /* その時刻の Monday week number */

    tm.tm_mon = 0, tm.tm_mday = 4;      /* その年の1月4日にセット */
    mktime(&tm);
    strftime(tmp, 3, "%W", &tm);
    jan4 = atoi(tmp);                   /* 1月4日の Monday week number */

    ret = today - jan4 + 1;             /* たいていこれが答えだが、*/
    if (ret == 0) {                     /* 0 だったら */
        tm = *tp;
        tm.tm_year--, tm.tm_mon = 11; tm.tm_mday = 31;  /* 前年の大晦日 */
        mktime(&tm);
        return weeknumber(&tm);         /* の week number を返す */
    }
    if (ret == 53) {                    /* 53 だったら */
        if (tp->tm_mday - tp->tm_wday >= 28) {
            return 1;                   /* 翌年の第 1 週ということもあり */
        }
    }
    return ret;
}
上のプログラムは、その原理に従って書いたものであるが、 コンパイラによっては --- というよりも「ライブラリ関数によっては」と言うべきか ---、 mktime() が正しく働かなかったり、 strftime() が Monday week number を正しく置き換えなかったりで、 なかなかうまく動かない。

【その2】 下の表は、 最初の場合分けの表に年内の通算日(元日が 1) から曜日(月曜が 1, 土曜が 6, 日曜が 7)を引いたものを、 右にカッコにいれてつけ足したものである。 それは週ごとに一定になることがわかる。 ただし、年が変わると一定ではない。 二年にまたがる週については、 左に前の年の分を、右に新しい年の分を示した。 前の年の分は「|」の左が平年の場合、右がうるう年の場合である。

case a)   1 |  1  2  3  4  5  6  7  (         0)

case b)   1 | 31  1  2  3  4  5  6  (364|365 -1)

case c)   1 | 30 31  1  2  3  4  5  (363|364 -2)

case d)   1 | 29 30 31  1  2  3  4  (362|363 -3)

case e)  53 | 28 29 30 31  1  2  3  (361|362 -4)
          1 |  4  5  6  7  8  9 10  (         3)

case f)  5? | 27 28 29 30 31  1  2  (360|361 -5)
          1 |  3  4  5  6  7  8  9  (         2)

case g)  52 | 26 27 28 29 30 31  1  (359|360 -6)
          1 |  2  3  4  5  6  7  8  (         1)
この値が -3 以上 3 以下の週が week number 1 であることがわかる。 それが 363 以上であれば翌年の第 1 週である。362 でも平年であれば同様。 -4 以下の場合は前年の最終週となる。 この原理で書いたのが次である。 関数 weeknumber() のみを示す。
/* (international) week number を返す */
int weeknumber(const struct tm* tp) {
    int mday = tp->tm_mday;
    int yday = tp->tm_yday + 1; /* +1 するのは元日を 1 にするため */
    int wday = tp->tm_wday;
    int diff, ret;
    int year;

    if (wday == 0) {    /* 日曜日を週の終わりにするための措置 */
        wday = 7;
    }
    diff = yday - wday;
    if (diff >= 363) {
        return 1;
    }
    if (diff == 362) {
        if (yday - mday == 334) {   /* 平年のとき */
            return 1;
        }
    }
    ret = (diff + 10) / 7;
    if (ret != 0) {
        return ret;
    }
        /* 残るは 0 のとき */
    year = 1900 + tp->tm_year - 1;  /* 前の年が */
    if (!(year % 4) && ((year % 100) || !(year % 400))) {   /* 閏年のとき */
        if (wday - mday <= 5) {
            return 53;
        } else {
            return 52;
        }
    } else {                                                /* 平年のとき */
        if (wday - mday <= 4) {
            return 53;
        } else {
            return 52;
        }
    }
}

【その3】 week number が 1 である週とは、1 月 4 日を含む週であった。 以下、A, B 二つの日について、 A のある時刻から B の同じ時刻までの時間を「日」を単位として表わした整数を 「A から B までの『日数』」と言うことにする。 1 月 4 日からその週の終わりの日曜日までの日数は 0 以上 6 以下である。 よって、ある時点の week number は、 その年の 1 月 4 日からその時点を含む週の終わりの日曜日までの日数を 7 で割った商に 1 を加えたものに等しいことがわかる。

年の初めや終わりには修正が必要だが、次のようにすれば簡単である。 年の初めについては、 もしもその年の 1 月 4 日からその日曜日までの日数が負になるなら、 その時点は week number の上では前年に属し、 前年の 1 月 4 日からの日数によって計算したものが結果となる。 年の終わりについては、 もしも翌年の 1 月 4 日からの日数が非負になるなら、 その時点は week number の上では翌年に属し、 その日数から計算したものが結果となる。 つまり、 「翌年の 1 月 4 日から」 「今年の 1 月 4 日から」 「前年の 1 月 4 日から」 の順で日数を計算し、 最初に非負になったものから答えを出せばよい。 (だから、返すのは week number だけでなく、 week number の上では何年に属するかも返すべきなのかもしれない。)

/* (international) week number を返す */
int weeknumber(const struct tm* tp) {
    double diff;    /* 差、単位は秒 */
    struct tm org, tmp;

    org = *tp;
    if (org.tm_wday != 0) {             /* その週の終わりの日曜日に変更 */
        org.tm_mday += (7 - org.tm_wday);
    }

    tmp = org, tmp.tm_mon = 0, tmp.tm_mday = 4;

    tmp.tm_year++;  /* 翌年の1月4日 */
    do {
        diff = difftime(mktime(&org), mktime(&tmp));
        tmp.tm_year--;
    } while (diff < 0);
    return ((int)(diff/(24L*60*60))) / 7 + 1;
}
上のプログラムでは引数として与えられた時刻そのままで計算しているが、 うるう秒があるとまずいかもしれない。 もしも 00 時 00 分 00 秒直前にうるう秒があって 23 時 59 分 60 秒がこの関数に渡されたとすると、 日付だけを 1 月 4 日に変えた時刻を mktime() にかけた際に翌日の 00 時 00 分 00 秒になってしまうかもしれないからだ。 また、日数の計算に difftime() を持ち出すのは大げさな気がする。 difftime() が double を返すため、浮動小数点ルーチンを組み込む必要も生じる。

【その4】 その3の関数に、自前の mydifftime() を組み合わせてみた。 日にちの差だけでよいので、 mydiffday() みたいなものを書くほうがいいのかもしれないが。 現時点での最終バージョンなので、最初のものと同じだが main() もつけてある。 また、上述のうるう秒の問題が気になったので tm_hour に 12 を代入してから計算している。

#include <stdio.h>
#include <stdlib.h> /* atoi */
#include <time.h>   /* struct tm */

long mydifftime(struct tm* t2, struct tm* t1);
long mytime(struct tm* t);
int weeknumber(const struct tm* tp);

int main(int argc, char* argv[]) {
    int year;
    char str[80];
    struct tm tm;

    if (argc != 2) {
        puts("年(西暦、4ケタ)をつけて動かしてください.");
        puts("その年のすべての日の week number を出力します.");
        return 1;
    }
    year = atoi(argv[1]) - 1900;
    tm.tm_year = year; tm.tm_mon = 0; tm.tm_mday = 1;
    tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0;       /* 1月1日にセット */
    while (mktime(&tm), tm.tm_year == year) {
        strftime(str, 80, "%Y-%m-%d (%w) week number ", &tm);
        printf("%s", str);
        printf("%2d\n", weeknumber(&tm));
        tm.tm_mday++;   /* 翌日に進める */
    }
    return 0;
}

/* (international) week number を返す */
int weeknumber(const struct tm* tp) {
    long diff;  /* 差、単位は秒 */
    struct tm org, tmp;

    org = *tp;
    org.tm_hour = 12;                   /* 正午ごろに変更 */
    if (org.tm_wday != 0) {             /* その週の終わりの日曜日に変更 */
        org.tm_mday += (7 - org.tm_wday);
    }
    mktime(&org);

    tmp = org, tmp.tm_mon = 0, tmp.tm_mday = 4; /* 1月4日 */

    tmp.tm_year++;  /* 翌年の1月4日 */
    do {
        mktime(&tmp);
        diff = mydifftime(&org, &tmp);
        tmp.tm_year--;  /* その年、前年と戻してゆく */
    } while (diff < 0);
    return ((int)(diff/(24L*60*60))) / 7 + 1;
}

/* 私家版 difftime() です。引数と返り値の型が元のと違う点に注意。*/
long mydifftime(struct tm* t2, struct tm* t1) {
    return mytime(t2) - mytime(t1);
}

/* 1970-01-01 からの秒数を返す。閏秒には対応していない。*/
long mytime(struct tm* t) {
    unsigned long days;     /* 1970-01-01 から数えて、前日まで何日? */
    days = (t->tm_year - 70) * 365 + (t->tm_year - 69) / 4 + t->tm_yday;
    return ((days * 24 + t->tm_hour) * 60 + t->tm_min) * 60 + t->tm_sec;
}

2000-12-31 (0) 01:29:00 +0900

上の「その4」ではうるう秒について気にしているが、 夏時間も問題になりえるのであった。 例えば、夏時間実施中の(午前)0 時 30 分は、 夏時間を実施していなければ前日の 23 時 30 分になる。 よって、月日だけを一月 4 日に変更して mktime() を呼ぶと、 一月 3 日の 23 時 30 分になってしまうはずである。

2003-12-23 (2) 19:45:41 +0900

C言語>一日の秒数は int に収まるとは限らないのだった

int が 2 バイトのとき 「int day = 24*60*60;」がだめなのは割と気づきやすいが、 「difftime(...) / (24*60*60) 」もだめなのだった。 「24L*60*60」とすべし。

2000-12-30 (6) 23:33:40 +0900

プロ野球>優勝目前のチームが「この引き分けは勝ちも同然だ」と言うわけ

優勝目前のチームが引き分けたとき、 「この引き分けは勝ちも同然だ」と、 監督や解説者が言うことがある。 「プロ野球>順位の決め方を考える際に図を使う (2000-12-29 (5) 01:41:05 +0900 づけ)」 のように図を書いて、理由を考えてみた。

 勝
 |
 |
 |
 |
 |
 |    B
 |    ・
 |    ・・C
 |   A
 |
 |
 |
 |
 |
 |
 |
 |
−+−−−−−−−−−−−−−−−−−負
 |O
Oが原点、Aがこの試合の前にいた位置である。 優勝目前なので勝ち数が負け数よりも多いから、 たとえばこのような位置にあったとしよう。 もしこの試合に勝っていればBに、 負けていればCにくる。 しかし引き分けたのでAのままだ。 半直線OA、OB、OCが横軸となす角がそのまま勝率を表わすわけではないことは 上述のところですでに述べた。 しかし、角AOB、角AOCはかなり小さいので、 「この引き分けと勝ちとの“距離”」と 「この引き分けと負けとの“距離”」とを比較するだけなら、 これらの角の大きさがそのまま“距離”を表わしていると言ってよい。 図からわかるように、角AOBのほうが角AOCより小さい。 勝率が高ければ高いほど、この差は大きい。 これが、「限りなく勝ちに近い引き分け」などと言われる理由ではあるまいか。

上の考察は、この試合が終わった時点だけの話だ。 実際にはペナントレースはまだ続く。

 勝
 |
 |
 |
 |
 |
 |    ・
 |    ・・
 |    ・・・
 |    ・・・・
 |    ・・・・・
 |   A
 |
 |
 |
 |
 |
 |
 |
 |
−+−−−−−−−−−−−−−−−−−−−負
 |O
この試合は引き分けたので相変わらずAの位置にいるが、 この時点で、全試合終了後の位置は、 仮に残り試合が4試合とすれば、上の「・」のどこかである。 これらの点の位置を“平均”したものが、 最終的な予想位置といえよう。 (引き分けがそれほど多いとは思えないから、 単純な意味での平均ではないが。)

もし勝っていれば、その“平均”は上に1マスずれていた。 もし負けていれば、右に1マスずれていた。 すると、それら三つの“平均”の位置関係は、最初の図と同じようになる。 よって、同じように考えて、同じ結論に至る。

2000-12-29 (5) 02:32:35 +0900

上のリンクはいまはった。それまでは a href タグをおいていなかった。

2006-05-10 (3) 02:16:14 +0900

プロ野球>順位の決め方を考える際に図を使う

プロ野球の順位は「勝ち数」で決めるべきか「勝率」で決めるべきか、 あるいは「勝ち越し数」で決めるべきか、 などの問題を考える際、図で考えるとわかりやすい(かもしれない)。

(「ゲーム差」も考えられるが、 これは勝ち越し数の差を二で割ったものにすぎない。)

縦軸(y 軸)に勝ち数を、横軸(x 軸)に負け数をとる。 すると、 各チームはシーズン初めには原点におり、 勝てば上へ 1 だけ、 負ければ右へ 1 だけ進む。 もしも引き分けがないものとすると、 各チームともシーズン終了後には直線「x + y = 試合数」 の上にくる。

 勝
 |
 \
 |\
 | \
 |  \
 |   \
 |    \
 |     \
−+−−−−−−\−負
 |
このとき、順位の決め方は明らかであろう。 しかし、引き分けで終わる試合があるルールでは、 必ずしもシーズン終了後にこの線の上に並ばない。 だから問題が起こるのだ。

「勝ち数」で競うなら、より上にあるチームが上の順位になる。 つまり、各チームが x 軸に平行な直線群のどれに乗っているかを考え、 より上の直線に乗っているチームが上の順位になる。

 勝
 |
 +
 +−
 +−−
 +−−−
 +−−−−
 +−−−−−
 +−−−−−−
−+−−−−−−−−負
 |

「勝ち越し数」なら、y - x が問題になるから、 45 度で右上がりの直線群のどれに乗っているかを考え、 より上の直線に乗っているチームが上の順位になる。

 勝
 |
 /
 |/
 / /
 |/ /
 / / /
 |/ / /
 / / / /
−+/−/−/−/−負
 |

「勝率」は y/(x+y) であるから、 原点を通るどの半直線の上に乗っているかで決まる。 より上に位置する半直線に乗っているほうが順位が上である。

ところで、「勝ち数」「勝ち越し数」の場合は、 “一位のチームと二位のチームの差”と “二位のチームと三位のチームの差”はどちらが大きいか、 などが図の上でも明らかである。 それに対し、「勝率」ではそれほど明らかではない。 二チームの差が、二つの半直線のなす角度に正比例しないからである。 以下、そのあたりを計算してみよう。

考えている半直線が x 軸となす角を a とすると y/x = tan(a) であるから、 勝率をρとすると

    ρ = y/(x+y) = 1/(x/y + 1) = 1/(1/tan(a) + 1)
となる。 一方、ρ = y/(x+y) の右辺の分母子を点 (x, y) と原点との距離で割れば ρ = sin(a) / (cos(a)+sin(a)) が得られる。 ここで ρ を a で微分すると
    dρ/da = {cos(a)(cos(a)+sin(a))-sin(a)(-sin(a)+cos(a))}/(cos(a)+sin(a))^2
           = 1/(cos(a)+sin(a))^2
となり、1 <= cos(a)+sin(a) <= ルート 2 であることを考えると 1 <= dρ/da <= 1/2 がわかる。 つまり、正比例はしないが、変化率は2倍の範囲でしか変わらないのである。

関数電卓を利用して ρ = 1/(1/tan(a) + 1) のグラフの概形を書けば以下のとおり。 縦軸(単位は度)が a, 横軸がρである。

  0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.0
 0 $----+----+----+----+----+----+----+----+----+----+-
   |   $
10 |      $
   |          $
20 |            $
   |               $
30 |                 $
   |                    $
40 |                      $
   |                        $
50 |                          $
   |                            $
60 |                               $
   |                                 $
70 |                                    $
   |                                      $
80 |                                          $
   |                                             $
90 |                                                 $
   |

2000-12-29 (5) 01:41:05 +0900

「<」をエスケープするのを忘れていたので、した。

2004-05-04 (2) 19:03:31 +0900

フォションの店先で「オトン」というのを見たが automne とは想像できず

ちょっと前、 名鉄丸越の地下のフォションの店で「オトン」 と書いて紅茶の宣伝をしていたが automne のこととは想像できなかった。 英語の「オータム」ならできるのに。

(この単語の二つ目の母音は鼻母音じゃなかったのか……。)

2000-12-29 (5) 01:11:47 +0900

フランス語のカタカナ書きが統一されていないのは英語ほど使われないから?

フランス菓子の説明に 《Gâteaux Voyage 〔ガトー・ボワイヤージュ〕》 と書いてあった。 「voyage は普通“ボヤージュ”じゃないのか? “ボン・ボヤージュ”って言うし」 と思ったが、 それもそんなに発音に近くない。 英語からの借用語のカタカナ書きは統一されていることが多く、 文句を言いたくもならないのは、 発音に忠実に写しているからではなく、 非常に頻繁に使われているからだろうか?

2000-12-29 (5) 01:08:20 +0900

「概形」(大体の形の意)という言葉があると思っていたが広辞苑にない

「グラフの概形は以下のとおり」 などと数学で使うと思っていたが、 広辞苑第五版にはない。

2000-12-29 (5) 01:04:48 +0900

“偽PC−VAN”として「ΡС−VAN」という名前を考えたっけ

パソコン通信PC−VANでは、 メッセージを書いた人の ID は必ず書き込まれるものの、 ハンドル(ペンネーム)は自分でタイトル行に書き込むようになっていたので、 「PC−VAN事務局」 などと名乗って注意力が不足している人をだますことが可能だった。 あとで文句を言われたとき 「『エノケン』じゃなくて『エノケソ』だ」 のように言い逃れのできる名前として 「ΡС−VAN事務局」という名前を考えたっけ。 ギリシア文字のローにロシア文字のエスだから「ローエスヴァン」。 どっちもロシア文字で「РС−VAN」(エルエスヴァン)というのも可能か。

付: 決してこのような人をだます行為を推奨しているわけではありません。

2000-12-28 (4) 23:28:30 +0900


すのもの Sunomono