Line counter

Line counter が公開になった。この問題、出力が 7 と 1 と 8 だけなので、「また、くだらない embed/random 問題かぁ」っと思ったが、行数を数える、ということ自体は、ゴルフとしては割と面白いと思ったので、“真面目に”やってみた。

vi

vi はいろいろな解法があり面白かった。

:%s/.*/+1
V{JS^R=^R"^H
^[ZZ

これで23B 。この解は、まず、各行を "+1" に置換したあと、全行を連結して結果の式("+1+1+1+1+1+1+1"といった式)を評価して行数を求めるというもの。

s^R=line("$")
^[lvG$dZZ

次は、行番号を line() 関数で取得するというもの。最終行は、移動して line(".") ではなく、line("$") で直接取れる。これで、21B 。この解では、行数を得たあとに、残りのデータを削除するのが若干 B を食う。で、考えたのが、以下。

VGr s^R=line("$")
^[ZZ

この解のアイデアは、まず、全行を "VGr " で、スペースに置き換えてしまう。そのあとで行数を数えて先頭行に書いている。これは、anarchy golf では、trailing space は無視されるという性質を使っているもの。これで、20B 。

r19@='J0^A'
lDZZ

最終的にたどり着いたのがこの 15B 。これは、マクロ実行により行の結合("J")が何回できるかを数えるという方法。マクロは "J" コマンドに失敗すると exit するので正しくカウントできる。カウンターは初めに "r1" で作っておき、マクロの実行ごとに "^A" でカウントアップしている。この解はコンパクトだが、行数が一桁であることを仮定している、ちょっと cheat 気味な解。
他の人の解は、もっと短くなっているが、それらは、"wc -l" を "!" で実行している cheat 解。やってて面白いのかな。くだらね。

C

C にとってはそんなに難しくはないが、43B と 42B の間にはちょっとした工夫がいる。42B トップは ush さんだが、私も同じ解にたどり着けた。inaniwa さんも同じだ。

n=48;main(b){for(;gets(&b);)n++;puts(&n);}    // 42B
main(n,b){for(;gets(b);)n++;putchar(n+47);}   // 43B

n を 48 で初期化しておいて、puts() に持っていくのが面白いところ。

bash

bash にとって、本問の問題は、最終行に改行がついていないところ。問題作者はたぶん意識していなかったのではないかと思うが、むしろその点が bash golf での工夫する点となり面白かった。
当初単に sed を用いて

sed -n $=

という 9B 解を作った。しかしながら、sed を使わない 9B を思いつき、bash の代わりに、zsh で投稿した。

rev|wc -l

rev コマンドが最終行に改行文字を補ってくれる。
このあと何か同様のコマンドがないかと探していたら、nl コマンドを見つけた。このコマンドは、各行に行番号を付けてくれるというもの。ただし、本問では、その行番号は使わず、単に、最終行に改行を補う目的で使っている。

nl|wc -l

これで、8B 。