Flower Fieldは、人気ゲーム「マインスイーパー」を心温まる形で作り直したゲームです。ゲームの目的は、庭にあるすべての花を見つけることです。その手がかりになるのが数字で、そのマスに上下左右と斜めに隣接している花の数を表しています。「Flower Field」は、イタリア、ドイツ、韓国、日本、台湾のMicrosoft Windows各国語版に収録されていました。
完成したFlower Fieldの庭にある空きマスに、花の数を書き込むのが課題です。
庭は長方形の盤で、マスは空きマス(' ')か花('*')のどちらかです。
空きマスごとに、そのマスに隣接する花の数(横・縦・斜め)を数えます。 隣接する花が1つもない空きマスは、空きマスのままにします。 それ以外の場合は、隣接する花の数で置き換えます。
たとえば、次のような5 x 4の盤が渡されることがあります(ここでは画面上に表示するため、空きマスを'·'という文字で表しています):
·*·*·
··*··
··*··
·····
コードはこれを次のように変換します:
1*3*1
13*31
·2*2·
·111·
テストでは、jqにいつもとは違うオプションが付いていることに気づくでしょう。
run jq -s -R -c -f flower-field.jq << 'END_INPUT'
これらは何でしょうか?
-s
これは「slurp」モードです。 入力をJSONオブジェクトのストリームとして扱う代わりに、 入力全体を1つの配列にまとめて読み込みます。
$ seq 5 | jq -c '.'
1
2
3
4
5
$ seq 5 | jq -s -c '.'
[1,2,3,4,5]
-R
-rはすでに見たことがあるかもしれません。これは「生の」文字列(引用符なし)を出力するためのものです。
-Rはその反対で、
入力の各行を1つの文字列として扱います。
2つの例を見てみましょう。
$ seq 5 | jq -R -c .
"1"
"2"
"3"
"4"
"5"
$ echo 42 | jq '. * 2' # input is a JSON number
84
$ echo 42 | jq -R '. * 2' # input is a JSON string
"4242"
この2つのオプションを一緒に使っても、結果は文字列の配列にはなりません。 行末の改行も含めて、入力全体が1つの文字列になります。
$ seq 5 | jq -s -R -c .
"1\n2\n3\n4\n5\n"
これをどう扱うかも、この演習のやりがいのひとつです。