literate C.js
つい最近は、あなごるの literate C という問題が終了した。この問題は、以下のようなルールになっている。
hoge fuga >hoge >fuga piyo >piyo
上記のようなテキストファイルがあったとする。
hoge
のように、行の最初の文字が>
でないならば、その行をコメントと呼ぶ>hoge
のように、行の最初の文字が>
であるならば、その行をコードと呼ぶ
行がコメントなら、/* hoge */
と出力し、コードなら、hoge
と出力する。ただし、2 行以上コメントが続く場合は、まとめて /*
と */
で括り、インデントを入れる必要がある。
すなわち、上記ファイルの正しい出力結果は以下となる。
/* hoge fuga */ hoge fuga /* piyo */ piyo
JavaScript で投稿したところ、単独トップを取ることができた。
for(d=0;;d=s&&">"!=s[0]?v=d?v+"\n "+s:s:(d&&p("/*",v,"*/"),p(s.slice(1))))s=readline(p=print)
これが、そのコードだ。サイズは 95B.
基本的なロジックはそのままに、わかりやすさを重視して改変すると、概ね以下のようになる。
for (d = false;;) { s = readline(); if (s && s[0] != ">") { if (d) v += "\n " + s; else v = s; d = true; } else { if (d) print("/*", v, "*/"); print(s.slice(1)); d = false; } }
一行だけ読み取り、それがコメントなら、v に追記していく。そうでなければ、v を出力し、かつ、現在行も出力する。
細かいところを省略すると、だいたい、そのような処理になっている。
変数 d には、直前の行がコメントであったかどうかの真偽値が入っている。それによって、コメントである現在行を v に追記するのか、それとも、v を現在行で上書きするのかという処理の分岐が行われる。加えて、現在行がコードであった場合、v を出力するかどうかの判定も行う。直前の行が、コメントなら、v を出力する必要があるが、コードなら、出力するわけにはいかないからだ。