LLまつりに行ってきた(シェル芸復習その2[3,4問目]の巻)

前回の続きです。
3問目:

https://twitter.com/usptomo/status/371095051826245632
次のechoから始めて4つの数字の間に + - * / の符号を入れ、100になる計算式をワンライナーで一つ作ってください
$ echo 56 2 8 9

今回解答を見た中で、一番狂ってる(褒め言葉)と思ったのが3問目でした。
てっきり「人が計算式を確定させて、それに従うようにテキストを整形する」というお題かと思ったら、というか、会場で質問をされていた方も、「テキスト整形だけでいいですか? それとも計算ロジックまで含めるの?」という意図で訊かれていたのではなかったのかなぁ。

さて、計算式の確定までコンピューターにヤラせるのであれば、頭の悪い方法ですが、ベタに総当りで行くのがまずは定石ですかね。
と、なると、配列を2つ用意して、1つには"+ - * /"を、もう一つには"56 2 8 9"を入れて、計算をさせながら、計算結果が100になる数式を探していくわけで。
えーっと、こんな感じのことができればいいのかな?

56 + 2 + 8 + 9 #=> 75 N.G.
56 + 2 + 8 - 9 #=> 57 N.G.
56 + 2 + 8 * 9 #=> -14 N.G.
56 + 2 + 8 / 9 #=> 58 N.G.
56 + 2 - 8 + 9 #=> 59 N.G.
:
:
:

こんな総当りで、結果が100になる行だけ抜き出します。
とりあえず、加減乗除演算子をforで回せば出すものは出せそう。いろいろ四苦八苦してみた結果はこんな感じ

a=(56 2 8 9)

$ for b1 in + - \* / ;do
>   f1="${a[0]} $b1 ${a[1]}"
>   for b2 in + - \* / ;do
>     f2="$f1 $b2 ${a[2]}"
>     for b3 in + - \* / ;do
>       f3="$f2 $b3 ${a[3]}"
>       ans=`echo "$f3" |bc`
>       if [ $ans -eq 100 ]; then
>         echo "$f3 = $ans"
>       fi
>     done
>   done
> done
56 / 2 + 8 * 9 = 100

うん、まごうことなき力技。次行きます。

4問目:
これまた設問ついーとは無いっぽい

http://ja.wikipedia.org/wiki/ISO_3166-1
(ISO 3166-1 --wikipedia)のページから、

アイスランド IS
アイルランド IE
アゼルバイジャン AZ
アフガニスタン AF

のように、国名と2レターコードの対のリストを作りましょう。

これも力技で解いていきます。該当のページをcurlで取得してファイルに格納すると、

<td><a href="/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Flag_of_Iceland.svg" class="image" title="アイスランドの旗"><img alt="アイスランドの旗" src="//upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Flag_of_Iceland.svg/25px-Flag_of_Iceland.svg.png" width="25" height="18" class="thumbborder" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Flag_of_Iceland.svg/38px-Flag_of_Iceland.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Flag_of_Iceland.svg/50px-Flag_of_Iceland.svg.png 2x" /></a> <a href="/wiki/%E3%82%A2%E3%82%A4%E3%82%B9%E3%83%A9%E3%83%B3%E3%83%89" title="アイスランド">アイスランド</a></td>
<td lang="en" xml:lang="en">Iceland</td>
<td>352</td>
<td>ISL</td>
<td>IS</td>
<td>北ヨーロッパ</td>
<td><a href="/wiki/ISO_3166-2:IS" title="ISO 3166-2:IS">ISO 3166-2:IS</a></td>
</tr>
<tr>
<td><a href="/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Flag_of_Ireland.svg" class="image" title="アイルランドの旗"><img alt="アイルランドの旗" src="//upload.wikimedia.org/wikipedia/commons/thumb/4/45/Flag_of_Ireland.svg/25px-Flag_of_Ireland.svg.png" width="25" height="13" class="thumbborder" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/4/45/Flag_of_Ireland.svg/38px-Flag_of_Ireland.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/4/45/Flag_of_Ireland.svg/50px-Flag_of_Ireland.svg.png 2x" /></a> <a href="/wiki/%E3%82%A2%E3%82%A4%E3%83%AB%E3%83%A9%E3%83%B3%E3%83%89" title="アイルランド">アイルランド</a></td>
<td lang="en" xml:lang="en">Ireland</td>
<td>372</td>
<td>IRL</td>
<td>IE</td>
<td>西ヨーロッパ</td>
<td><a href="/wiki/ISO_3166-2:IE" title="ISO 3166-2:IE">ISO 3166-2:IE</a></td>
</tr>
<tr>
<td><a href="/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Flag_of_Azerbaijan.svg" class="image" title="アゼルバイジャンの旗"><img alt="アゼルバイジャンの旗" src="//upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Flag_of_Azerbaijan.svg/25px-Flag_of_Azerbaijan.svg.png" width="25" height="13" class="thumbborder" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Flag_of_Azerbaijan.svg/38px-Flag_of_Azerbaijan.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Flag_of_Azerbaijan.svg/50px-Flag_of_Azerbaijan.svg.png 2x" /></a> <a href="/wiki/%E3%82%A2%E3%82%BC%E3%83%AB%E3%83%90%E3%82%A4%E3%82%B8%E3%83%A3%E3%83%B3" title="アゼルバイジャン">アゼルバイジャン</a></td>
<td lang="en" xml:lang="en">Azerbaijan</td>
<td>031</td>
<td>AZE</td>
<td>AZ</td>

こんな感じのデータが得られます。
これを只管解析していくと、国名に関しては

$ curl http://ja.wikipedia.org/wiki/ISO_3166-1 |grep 'class="image" title=' |awk -F\" '{print $NF}' |sed -e "s/^.//" |sed -e "s/.\/a..\/td.$//" |grep -v '^\/.$'

これで、2レターコードに関しては、

$ curl http://ja.wikipedia.org/wiki/ISO_3166-1 |grep '^.td.[A-Z][A-Z].\/td.$' |sed -e "s/^.td.//" |sed -e "s/.\/td.$//"

で、取ってくることができそうです。後はこれを連結できれば良いので、これまたpasteでも使ってみましょうか。

$ curl http://ja.wikipedia.org/wiki/ISO_3166-1 |grep 'class="image" title=' |awk -F\" '{print $NF}' |sed -e "s/^.//" |sed -e "s/.\/a..\/td.$//" > ./filex ;curl http://ja.wikipedia.org/wiki/ISO_3166-1 |grep '^.td.[A-Z][A-Z].\/td.$' |sed -e "s/^.td.//" |sed -e "s/.\/td.$//" > filey ;paste ./filex ./filey ;rm ./filex ./filey

うん。汚ねェェェェェェェェェなぁ。

続きはまた後日。