シェル芸でズンドコキヨシ
おしらせ:今回はjotコマンドあります
概要
最近流行の「ズンドコキヨシ問題」を、シェルワンライナーで解いてみました。
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも (@kumiromilk) 2016年3月9日
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた
解
jot -r 0 | awk '$0=$0%3{zd=substr($0 zd, 0, 5);if($0==1){w="ズン"}else{w="ドコ"}print w, zd}' | awk '{print $1}/21111/{print "キ・ヨ・シ!";exit}'
解説
分解して順番に解説していきます。
jot -r 0
jotコマンドは、任意の個数・任意の範囲の数値を出力するコマンド(GNUのseqみたいなもん)ですが、「-r」オプションをつけると、指定した回数だけランダムな数値を出力します。
また、回数として引数に0を指定すると、無限に値が出力されます。
これを組み合わせることで、ランダムな数値を無限に出し続けることができます。
こんな感じ。
$ jot -r 3 63 67 52 $ jot -r 0 65 50 49 100 74 84 38 (以下、止めるまでずっと続く…)
jot -r 0 | awk '$0=$0%3'
awkのパターンで、$0に「3で割った余り(つまり、0~2)」を設定します。
パターンで代入結果が「0」になると出力されないので、結果的に「1」か「2」だけがアクションに渡されます。
こんな感じ。
$ jot -r 0 | awk '$0=$0%3' | head -5 1 1 2 2 2
jot -r 0 | awk '$0=$0%3{zd=substr($0 zd, 0, 5);if($0==1){w="ズン"}else{w="ドコ"}print w, zd}'
「ズン」とか「ドコ」とかそういう難しいことは苦手なので、数字で考えます。
- $1…値が1の時は「ズン」、2のときは「ドコ」を$1に出力
- $2…過去5回分の「1」or「2」を逆順に累積(逆順になっているのはsubstrで前からカットするため)
出してみるとこんな感じ。
$ jot -r 0 | awk '$0=$0%3{zd=substr($0 zd, 0, 5);if($0==1){w="ズン"}else{w="ドコ"}print w, zd}' | head -8 ドコ 2 ドコ 22 ズン 122 ドコ 2122 ドコ 22122 ドコ 22212 ドコ 22221 ドコ 22222
jot -r 0 | awk '$0=$0%3{zd=substr($0 zd, 0, 5);if($0==1){w="ズン"}else{w="ドコ"}print w, zd}' | awk '{print $1}/21111/{print "キ・ヨ・シ!";exit}'
最後のawkで、パターンとアクションの組が二つ出てきます。
1つめ…パターンなし、アクションは「{print $1}」
$1、つまり「ズン」か「ドコ」を出力
2つめ…パターンは「/22221/」、アクションは「{print "キ・ヨ・シ!";exit}」
「21111」、つまり、過去5回が「ズン ズン ズン ズン ドコ」だった行の時だけアクションが実行されます。
アクションは「キ・ヨ・シ!」を出力して終了。
……ということで、久々のjot芸でした。