めちゃくちゃだよお・・・
第35回またまためでたいシェル芸勉強会の大阪サテライトに参加してきました。
この日大阪は寒かったので久しぶりにウインドブレーカーを取り出したんですがストリーミング配信の先は半袖だったので驚きました・・・
今回もはちゃめちゃな問題が多くて勉強になりましたし、倒れました。
【問題と解答】jus共催 第35回またまためでたいシェル芸勉強会
せっかく参加して何問か解けたので残しておこうと思います。想定解のはTogetterなりを見てくださいね。
問1
curl parrot.live
から流れてくるアニメーションをファイルに保存して再生する問題。いきなりあたまおかC
ファイルの種類に制限がなかったのでスクリーンキャプチャしてgif
にしました(反則)
想定解ではawk
でsleep
しながら1行ずつ出力するものでした。awk
ってsleep
もできちゃうんですね知りませんでした。
ところでこのアニメーションめっちゃ面白いっすね・・・
問2
数値と文字がペアになっている複数行のファイルから数値の行に文字を表示する。ファイルに存在しない数値の行は空行。
cat herohero | sed 'y/1234567890/1234567890/' | sed -E 's/(へ|ろ)/ \1/g'| awk '{x[$1]=$2}END{for(i=1;i<=13;i++) print x[i]}'
awk
の連想配列を使えば楽だなーと思ったので整形してからawk
へもっていきました。呟いた後で他の方の解答を見ていたんですがsed 'y/.../'
のところはnkf -Z
の方がスマートでいいですね。さらにsed -E
の部分もろ|へ
をキーにするんじゃなくて[0-9]+
の正規表現の方がいいですね。勉強になります。
あとはsed
のc
も-f-
も初めて知ったのでこれから使えたらカッコいいですね
問3
また数値と文字がペアになっている複数行のファイルがあるので、これを今度は集計する。
集計自体は難しくないけど出力の成形が少し面倒らしい
cat data |sort -k 1|uniq -c|awk '{x[$2]=x[$2]" "$3":"$1}END{for(i in x) print i,x[i]}'
直前のことが頭に残ってたのでawk
の連想配列を使うパターンで解きました。
dataを集計すると
$ cat data | sort | uniq -c
2 1 A
3 1 B
1 2 A
3 2 C
3 3 B
1 3 C
1 3 D
1 4 C
となるので、2レコード目をキーにして出力を整形しました。これは簡単(基準がおかしくなっています)
別解ではyarr
というコマンドがあるのでそれで一発だよ。というのがありました。
後で気づいたんですけですけどsort
の-k 1
はいらないっすね・・・。
問4
ひらがなで名前っぽい単語をランダムに生成する問題。名前っぽいとはみたいな
zsh -c "echo {あ..ん}"|xargs -n1|shuf -n6|tr -d '\n'|sed 's/.../& /'|awk 1
最初に作ったのがこれでした。zsh
のブレース展開で平仮名を作って6個選んで3つずつに分けて名前っぽく・・・
なりませんでした(なるわけがない)
なので次は名前ランキングみたいなのからスクレイピングすることにしました。
curl https://st.benesse.ne.jp/ninshin/name/2017/name-ranking.html | grep -oP "[あ-ん]+"|awk 'length($1)==3'
日本語だけ取り出した後、3文字のやつは名前と決め打ちで抽出しました。けっこうそれっぽかった
ゆうま
ひなた
あおい
みなと
そうま
はると
はると
そうた
あさひ
そうた
ゆうと
ゆいと
あおい
やまと
...
faker
を使うのかなーとか思っていたら適当に列挙して、mecabに通した後人名だけ取り出すというパワーシェル芸が想定解だったみたいです。すごい
問5
echo 響け!ユーフォニアム
からはじめて下みたいな出力を得る。ぼくはこのアニメ見てました
響け!ユーフォニアム
響け!ユォニアム
響け!ニアム
響けアム
響ム
ム響
ムアけ響
ムアニ!け響
ムアニォユ!け響
ムアニォフーユ!け響
響け!ユーフォニアム問題は様々なパターンでの出題がありますが一問も解けたことがないです。これもそうでした。あたまいたい
少し前のLTでもあったように少しずつ解に近づけていく方法で行こうと思いましたが時間切れ。
想定解はsubstr
でゴリゴリ削ってゴリゴリ並べて上を作った後、下の三角形をrev
とtac
で作るものでした。このときmoreutils
に含まれているpee
を使うと楽だよというのを知りました。tee
の出力先がコマンド版みたいなやつです。前々から欲しかったコマンドなので知れてうれしかったです。どうでもいいんですけどpee
っておしっこですよね
この問題は他の方の解答を眺めていました。vimシェル芸とかホントすごい・・・
問6
素因数分解したときに23以下の数だけで構成される自然数を1985個だす問題。急に数学かよ!?と思ったら数学オリンピックからの引用だそうで。競プロにもこんな問題ありそう
これは正規表現を書いていたら頭おかしくなってました。前問のせいですかね。
想定解では、factor
は小さい順に素因数が出力されるのでawk
の$NF
を見て23以下かを見るだけでOKのようですね。かしこい
問7
文字列の素数番目を読むと意味を成すような文字列を作る問題。楽そう(基準がおかしくなっています)
join <(seq 50|factor|awk 'NF==2{print $2}'|cat -n) <(echo 響け!ユーフォニアム|grep -o .|cat -n)| awk '{x[$2]=$3}END{for(i=0;i<=29;i++)print x[i]==""?"ユ":x[i]}'|tr -d '\n'|awk 1
響け!ユーフォニアム問題が解けなかった腹いせに響け!ユーフォニアムでやってみました
ユユ響けユ!ユユユユユーユフユユユォユニユユユアユユユユユム
10番目の素数が29なのでそこまでの配列をawk
で作って素数じゃないところはユで埋めます。いままでjoin
でやってきましたがpaste
のが便利なんじゃないかというね?
せっかくsed
のc
を覚えたので使って解いたのがこっちです
seq 10000|factor|awk 'NF==2{print $2}'|paste - <(echo 響け!ユーフォニアム|grep -o .)|head -n10|awk '{print $1"c"$2}'|sed -f- <(yes)|head -n29|sed 's/y/ユ/g'|tr -d '\n' |awk 1
問8
問6で作った自然数リストから4つ選んで掛け算したときの値がある値の4乗になっている組み合わせを1つみつける問題。全部探せだと無理だなってなった
最初誤読していて、リストの中から4乗の数を探すのかと思って解いたのがこれです。
$ yes|awk '{print "echo $(("NR"*"NR"*"NR"*"NR"))"}'|head -n30|bash|while read L;do cat a|grep -w $L;done
1
16
81
256
625
1296
2401
4096
6561
10000
14641
これは本当の答えではないんですが、ここから4つ選んで掛け算すれば4乗の数が作れるのでそれでOKということですね。
yes|awk '{print "echo $(("NR"*"NR"*"NR"*"NR"))"}'|head -n12|bash|xargs -I@ grep -w @ a|shuf -n4|xargs|sed 's/ /*/g'|bc|factor
4つランダムに取り出して計算、factor
にかけます。これも何とか解けました。
1から1985個の条件に合う自然数は20,111
が最後なので4乗の数は11個しかないです。これなら結局全列挙できそうですねこれ
ところで記事を書いてて思ったんですが、awk
で計算式を作ってbash
に計算させてますがこれawk
で完結しますよね・・・
yes | awk '{print NR*NR*NR*NR}' | head -n12 | shuf -n4 | xargs | sed 's/ /*/g' | bc | factor
LT
今回も難読化シェル芸でLTさせていただきました!!!難読化シェル芸だいすき!時間があったら詳細を記事にしてみたいとかおもったりします!せかしてくれたら早めにやると思います!!
www.slideshare.net
はじめはkanataさんによるA,z,記号,1,2でやる難読化シェル芸をみて「ヤバすぎ」とおもったんですが、面白そうだったので少しやってみたらなんかすごいことになりました。
C#のラムダとかで
list.Select(_=>_....)
みたいに書くのでそれがずっと頭に残ってました。だからどうとかではないんですが、頭はおかしくなりました。
何人かの方に気に入っていただけたようでとっても嬉しいです。いつか__
で会話する日が来るといいですね(来ない)
まとめ
今回もとても楽しかったです!いつも大阪会場を用意してくださる方、主催の方々、ありがとうございました!(名前を出していいのかわからないのでぼかしています)