引用元: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();を足すのでもよい。