Qiita Engineer Festa 2024(キータ・エンジニア・フェスタ 2024) - Qiita
において、約1ヶ月で38記事という大量の記事の投稿を要求されることがわかった。
そこで、あまりコストをかけずに記事数を稼ぐ方法を考えた結果、「Welcome to AtCoder を様々な言語で解く」ことを思いついた。
単に解くだけでなく、使用する言語仕様の解説を入れれば、記事として一応成立するだろう。
Welcome to AtCoder
PracticeA - Welcome to AtCoder
Welcome to AtCoder では、以下の形式で整数 $a$, $b$, $c$ および文字列 $s$ が入力として与えられる。
a
b c
s
この入力をもとに、与えられた整数の和 $sum = a + b + c$ および文字列 $s$ を、以下の形式で出力することが求められる。
sum s
今回用いる jq の機能
コマンドラインオプション
ルール - AtCoder Beginners Selection
を参照すると、AtCoder における jq はコマンドラインオプション -MrRs
を指定して実行されることがわかる。
これらのオプションは、それぞれ以下の意味である。
オプション | 意味 |
---|---|
-M |
出力に色をつけない |
-r |
文字列を出力する際、JSON形式でクォートせずそのまま出力する |
-R |
入力をJSONとしてパースせず、文字列として解釈する |
-s |
フィルタを入力の行ごとに実行せず、全体に対して一度実行する |
すなわち、
- 入力全体を一度に処理する
- 余計な加工はせず、入力を文字列として受け取り、文字列はそのまま出力する
という設定になっていることがわかる。
また、「-r
と同様の動作をするが、結果の出力後に改行を出力しない」オプション -j
が存在することから、逆に AtCoder で使われているオプション -r
は結果の出力後に自動で改行を出力すると推測できる。
フィルタ
jq では、入力を「フィルタ」で処理することにより加工し、出力を生成する。
一つまたは複数のフィルタを受け取り、それを用いた新たなフィルタを構築する構文もある。
要素の取り出し .[添字]
.[添字]
は、配列を入力として受け取り、「添字」で指定する要素を出力するフィルタである。
部分列の取り出し .[開始点:終了点]
.[開始点:終了点]
は、配列を入力として受け取り、添字が「開始点」以上「終了点」未満の部分を切り出した配列を出力するフィルタである。
また、文字列を入力として受け取り、同様に部分文字列を出力することもできる。
文字列の数値への変換 tonumber
tonumber
は、文字列を入力として受け取り、それが表す数値を出力するフィルタである。
数値が入力された場合は、それをそのまま出力する。
文字列の分割 split(正規表現; フラグ)
split(正規表現; フラグ)
は、文字列を入力として受け取り、それを「正規表現」にマッチする場所で区切った結果の (文字列を要素とする) 配列を出力するフィルタである。
配列の文字列化 join(文字列)
join(文字列)
は、配列を入力として受け取り、その要素を「文字列」を区切りとして結合した文字列を出力するフィルタである。
加算 左辺 + 右辺
左辺 + 右辺
は、以下の動作をするフィルタである。
- 全体の入力を「左辺」のフィルタと「右辺」のフィルタそれぞれで入力として処理する
- 「左辺」のフィルタの出力に「右辺」のフィルタの出力を「加算」した結果を全体の出力とする
「加算」とは、数値なら足し算、文字列なら結合、などである。
パイプ 左辺 | 右辺
左辺 | 右辺
は、以下の動作をするフィルタである。
- 全体の入力を「左辺」のフィルタの入力として処理する
- その出力を「右辺」のフィルタの入力として処理する
- その出力を全体の出力とする
列の結合 左辺 , 右辺
左辺 , 右辺
は、以下の動作をするフィルタである。
- 全体の入力を「左辺」のフィルタと「右辺」のフィルタそれぞれで入力として処理する
- 「左辺」のフィルタの出力(列)の次に「右辺」のフィルタの出力(列)を結合した列を全体の出力とする
配列化 [フィルタ]
[フィルタ]
は、以下の動作をするフィルタである。
- 全体の入力を「フィルタ」で入力として処理する
- その出力(列)を要素とする1個の配列を全体の出力とする
すなわち、複数の値からなるデータを、それらを複数の要素として格納した配列という1個の値からなるデータに変換する。
たとえば、前述の 左辺 , 右辺
と組み合わせて [左辺 , 右辺]
とすることで、「左辺」の出力と「右辺」の出力を要素としてもつ配列を生成できる。
配列の各要素の処理 map(フィルタ)
map(フィルタ)
は、配列を入力として受け取り、その配列の各要素を「フィルタ」の入力として処理した結果 (出力) を同じ順で格納した配列を出力とするフィルタである。
提出コード
split("[ \n]"; "") | [(.[0:3] | map(tonumber) | .[0] + .[1] + .[2]), .[3] ] | join(" ")