引用元:https://www.ioccc.org/1996/westley.c
審査員・作者による説明:https://github.com/ioccc-src/winner/blob/main/1996/westley.hint
動作
見た目を設定できる時計。
実行には、コマンドライン引数でテンプレートを与える必要がある。
westleyを実行するシェルスクリプトが3つ添付されている。
clock1は柱時計。
13:00過ぎに実行した例。
$ gcc -m32 -o westley westley.c
$ ./clock1
-<<==O==>>-
--====v====--
| . |
| * |
| |
| 0 |
| |
| |
| |
=============
\ /
\ /
| |
| | |
| | |
| | |
| | |
| O |
| |
)-----------(
| |
=============
clock2は逆向きに進む置き時計。
$ ./clock2
)-=*=-(
--===-=-===--
) x (
| X |
| |
| 0 |
| |
| |
) (
]]==-----==[[
) | (
-----------
clock3はゲージ表示。
$ ./clock3
..3..6..9..12 Hours
|
|
----.----10---.----20---.----30---.----40---.----50---.---- Minutes
clock1からclock3は./westleyを引数付きで呼び出すスクリプトになっている。westley自身のコマンドライン引数の意味は次の通り。
- 第1引数:分のマークを置く位置のマップデータ
- 第2引数:時のマークを置く位置のマップデータ
- 第3引数:分と時のマーク
- 第4引数:時計のテンプレート
解説
これがたった92バイトで実現されているのには心を動かされる。
localtime
の返り値の時と分をマップデータで引いて、テンプレート中のその位置に指定されたマークを置く、というのが極めて簡潔に実現されている。
localtime()
の返すstruct tm*
をint*
とみなして時と分を読み出している。
argc
が初期状態で5なので、argc/=2
をループの条件とすることで、2、1となる。
2はlocaltime()
の返り値であるstruct tm
の3番目のフィールド、つまりtm_hour
に対応する。
1は2番目のフィールド、つまりtm_min
に対応する。
実に巧妙。
localtime
が返すポインタを暗黙的にint
として扱うので、-m32
が必要。
プロトタイプ宣言int *localtime();
を足すのでもよい。