Selection(≒drkenさんの精選10問)を解いてみたよ!(ただし1問はおそらくTLEする)jqコマンドって?主にJSONを加工するのに使われるコマンドです。以下のjsonを考えます。}]このjsonに対して、関東エリアの売り上げの合計を求めて、末尾に「万円」をつけて出力したいと思います。jqを使うと、以下のような短いコマンドで実現することができます。Manual』をざっくり日本語訳してみました』に大変詳しいです。Selectionを解くための最低限の説明に留めます。jqのフィルターの仕組みjqコマンドの一つ目の引数をフィルターと呼びます。パイプ(|)で繋がれた複数のフィルターの形をしています。以下の例は、フィルターの入力として1が渡され、最終的に"数字は12"が出力される例です。.'"数字は12"以下のように処理が進みます。2というフィルターの入力として渡されます。このフィルター中の.は入力を表します。出力は入力を2倍した値、すなわち2になります。10というフィルターの入力となり、12が出力されます。"12"が出力されます。最終的に"数字は12"が出力されます。複数のデータが入力として渡される例フィルターには複数のデータが入力として渡され得ます。複数のデータと1つの配列を渡すのはjqでは区別されていることに注意してください。.'"数字は12""数字は14""数字は16"今回よく出てくる機能.データ自身を表します。'.'1select(条件)データを下流に流すかどうかを振り分けます。条件が真のときはデータを素通りさせ、条件が偽のときはデータを流しません。(end-1)の複数の数値データを生成します。'range(1;5)'1234[複数のデータ]複数のデータを一つの配列にまとめ上げます。4][]配列を複数のデータに分解します。$nameデータを変数に束縛します。$input'33map(フィルター)配列のそれぞれの要素にフィルターを適用します。30][i]配列のi番目の要素を取り出します。3あとは問題の解答を見ながら解説していきます。断り書きOtoshidamaは間違いなくTLEします。inputで、入力コードはファイルcode.jqとして保存され、テストケース入力はファイルinputにあるとします。Selectionの問題の解答を載せていきます。問題へのリンクは各セクションのタイトルをクリックすると辿れます。\($input[2])"数を3つ、文字列を1つ受け取り、数の和と文字列を1行にまとめて出力する問題です。$b)"のような形をとり、\(と)で囲まれた範囲が式として計算されて埋めこまれます。end2数の和の偶奇を判定する問題です。入力を空白区切りで配列にし、それぞれの要素を文字列型から数値型に変換します。2行目には要素が2つの配列データが1つ渡っています。jqではifが使えるので、ifで偶奇を場合わけしています。.[1]でその配列の最初の値、2番目の値を取り出し足し合わせて、2で割ったあまりが0かどうか評価しています。length文字列中の1の数を数える問題です。入力文字列を文字ごとに分解し、"1"と等しい要素のみを残し、最後に定義済みフィルターlengthで配列の長さを取得しています。min与えられた数列のうち、2で割り切れる回数が一番少ない数について、その割り切れる回数を答える問題です。jqでは関数/フィルターが定義できます。1行目は、引数nを受け取り、nが2で何回割り切れるかを返す関数twos(n)を再帰で定義しています。配列の各数に対してtwosを適用して2で割り切れる回数の数列に変換し、minフィルターで最小の数を返しています。length500円玉A枚、100円玉B枚,50円玉C枚を持っている中で、X円の払い方が何通りあるかを数える問題です。"")は、split("\n")が末尾の改行の後を読んで空文字列を最後に生成するため、それを除くために必要になっています。1)により、0~Aのそれぞれのデータを生成し、それぞれを$aと名付けています。そのそれぞれが$aに束縛された状況に対して、またさらに0~Bの$bを定義しています。全体として、(A+1)*(B+1)*(C+1)通りのデータが処理されています。$c)の組み合わせのみを残しています。ここまで全体が[と]に囲まれていることによって、この払える組み合わせの数列が生成され、最後にlengthでその数を数えています。add1以上N以下の整数のうち、各桁の和がA以上B以下であるものの和を求める問題です。1)で1以上N以下の整数それぞれのデータを生成しているのですが、問題は次のselectの中身です。A以上B以下になっている」ようなものだけを残しています。和を取ろうとしているのは加工した後の数ではなく、加工前の数なので、ここまでの加工処理を全部selectの中身に押し込めて、外では元の数字がパイプに流れるようにしています。あとはこれを[と]で配列にまとめ上げて、addで合計するだけです。add)配列を降順にソートして、偶数番目の和から奇数番目の和を引いて出力する問題です。to_entriesです。配列の値}に変換して新たな配列を作ってくれます。add)で、それぞれの要素に対し「偶数番目の要素のみを残し、それぞれに対しvalueキーの値を取り出す」ことをして、その後配列の値を合計しています。length与えられた数列が、何種類の異なる数からなっているか数える問題です。それをするuniqueというフィルターがあるので、これを適用して配列の長さを数えるだけです。end合計N枚のお札で、合計金額がY円であることがありえるかどうか、ありえたらその組み合わせを一つ答える問題です。1行目から7行目までの大きな[]でありえる組み合わせの配列を手に入れ、ありえる組み合わせが1個以上あるかどうかで場合分けしています。end与えられた文字列がある正規表現に一致するか判定する問題です。jqにはまさに正規表現を扱うtestというフィルターがあります。y)にいなければならない」という形の制約が複数与えられるので、それが満たせるかどうか判定する問題です。y)に移動できるか?」という形の制約に変換しています。これに対し、ちょうどt秒後にその地点に到達可能であるかどうかのboolを返すreachableというフィルターを作り、all関数で、全ての制約がreachableであるかどうかをチェックしています。まとめjqコマンドは主にjsonの整形をするために使われるコマンドですが、そのフィルターの表現力はかなり高く、また、フィルターはかなり書きやすいし、記述量も少なくてすみます。Selectionの問題をかなり簡単に解くことができました。jqコマンドの使いやすさ、言語としての面白さが伝わってくれたら幸いです。upLoginユーザーは見つかりませんでした。