もとねた: 「ずんだのハロウィン問題 Ruby編」
1行野郎は男の浪漫--ということで、保守性や可読性を無視して、上記記事の条件を満たすワンライナーを書いてみました。
echo "trick treat sushi poyayou tamakatsu" | sed 's/\s/\n/g' | shuf -n 1 | awk '{print $0; print match($0, /^tr/) ? "happy halloween" : "sleepy" }'
さすがに読みずらすぎるので、わかりやすく整形し、適宜コメントを加えたものが以下になります。
echo "trick treat sushi poyayou tamakatsu" |
# 空白区切りを改行区切りに変更する。
sed 's/\s/\n/g' |
# 入力をシャッフルし、最初の1行を取り出す。
shuf -n 1 |
# 入力の内容にかかわらず、その内容をそのまま出力した後
# 入力がtrickまたはtreatの場合は、happy halloweenを出力する。
awk '{
print $0;
print match($0, /^tr/) ? "happy halloween" : "sleepy"
}'
もうちょっと工夫できそうですね(´・ω・`) とくに最後のawkは無理やり感が出ている。ここもパイプでスマートに書くことができれば、シェル芸人の仲間入りができる--はず。
おまけとして、以下のようなスクリプトを作りました。
seq 1000 | while read x; do
echo "trick treat sushi poyayou tamakatsu" |
sed 's/\s/\n/g' |
shuf -n 1 |
awk '{print $0; print match($0, /^tr/) ? "happy halloween" : "sleepy" }'
done > zunda.log
これは問題の1行野郎を1000回実行し、その出力結果をzunda.logに記録するというものです。実行後に生成されるzunda.logの内容は膨大なものになるため、とりあえず前の30行だけ見てみましょう(head -n 30 zunda.log)。
poyayou
sleepy
poyayou
sleepy
tamakatsu
sleepy
sushi
sleepy
tamakatsu
sleepy
trick
happy halloween
treat
happy halloween
poyayou
sleepy
poyayou
sleepy
poyayou
sleepy
sushi
sleepy
sushi
sleepy
tamakatsu
sleepy
treat
happy halloween
treat
happy halloween
trick, treat, sushi, poyayou, tamakatsuがランダムに生成され、trickまたはtreatの場合は続いてhappy halloweenが、それ以外の場合はsleepyが出力されている状態が確認できますね。ちなみにそれぞれの単語の出現回数は次のようなコマンドで確認することができます。
cat zunda.log | sort | uniq -c | sort -n
この実行結果は以下の通りで、それぞれの単語がある程度均等に出力されていることが分かります。また$165+179+196+223+237=1000$となり、1000回ちょうど実行されていることも確認可能です。
165 trick
179 sushi
196 treat
223 poyayou
237 tamakatsu
361 happy halloween
639 sleepy