ABC266のawkの最短解答は、現在次のもののようです。(私の書いたコードではありません)
$0=$(gsub(_,FS)/2)
https://atcoder.jp/contests/abc266/submissions/34440987
この回答が面白かったので、以下にどのようなコードであるかの解説を書きます。
awkのプログラムは 条件 { 処理 } という形式で記述され、(デフォルトでは)入力行ごとに「条件が真(0でない)であれば処理を行う」となっています。
例:
$ echo "hello" | awk '1{print "yes"}は、yesを出力する$ echo "hello" | awk '0{print "yes"}'は何も出力されない
今回は{処理}が記述されていません。このときは{print $0}が省略されているとして、$0の値が標準出力されることになっています。 ($0は入力行を表します)
例:
$ echo 'hello' | awk '1'はhelloが出力される$ echo 'hello' | awk '0'は何も出力されない
$0は特別な変数で、入力行を初期値としてプログラムが実行されます。
ただし、プログラム中で自由に代入できます。
$数字 は、$0 を区切り文字FS(デフォルトでは空白) で区切ったときの数字番目の文字列が返されます。
例:
$echo 'h e l l o' | awk "{print $2}"はeを返す
$0は入力行全体が入っている変数ですが、代入すれば上書きできます。
$0=で始まっているので、今回は 条件 が代入式で真になります。更にパターンが省略されているので、代入された値が最後に出力されます。
gsubは組み込みの関数です。第一引数に正規表現、第二引数に置換先文字列、第三引数に置換対象変数が渡されます。実行すると、置換対象変数の値が直接書き換わり、置換回数が戻り値になります。
- 第一引数: 置換時にマッチさせる正規表現を渡します。今回
_は未定義変数なので、''(空文字) と同等になります。空文字のときはすべての場所にマッチします - 第二引数: 置換先文字列を渡します。今回の
FSは、デフォルトで(スペース)が入っている変数です - 第三引数: 置換対象変数を渡します。省略されると
$0を指定したのと同等になります - 戻り値: 置換回数が返ります。今回であれば、実行前の
$0の文字数+1が返ります。
実行すると、$0のすべての文字がFS(空白)でバラされたものに置き換わります。
例えば実行前の$0がhelloのとき、次のようになります
- 実行後の
$0:h e l l o - 実行時のgsubの戻り値: 6
例:
$ echo 'hello' | awk '1{gsub(_,FS); print $0}'
h e l l o
$ echo 'hello' | awk '1{print gsub(_,FS)}'
6
$0=$(gsub(_,FS)/2)が実行されると、入力文字列を空白で区切った文字列を、入力文字列で区切ったときの、((入力文字列+1 )/ 2)番目の値が出力されます。これは問題の条件と一致します。