たいちょーの雑記

ぼくが3日に一度くらい雑記をかくところ

第35回シェル芸勉強会に参加しました

めちゃくちゃだよお・・・

第35回またまためでたいシェル芸勉強会の大阪サテライトに参加してきました。
この日大阪は寒かったので久しぶりにウインドブレーカーを取り出したんですがストリーミング配信の先は半袖だったので驚きました・・・

今回もはちゃめちゃな問題が多くて勉強になりましたし、倒れました。

【問題と解答】jus共催 第35回またまためでたいシェル芸勉強会

せっかく参加して何問か解けたので残しておこうと思います。想定解のはTogetterなりを見てくださいね。

問1

curl parrot.liveから流れてくるアニメーションをファイルに保存して再生する問題。いきなりあたまおかC

ファイルの種類に制限がなかったのでスクリーンキャプチャしてgifにしました(反則)

想定解ではawksleepしながら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]+正規表現の方がいいですね。勉強になります。

あとはsedc-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でゴリゴリ削ってゴリゴリ並べて上を作った後、下の三角形をrevtacで作るものでした。このとき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のが便利なんじゃないかというね?
せっかくsedcを覚えたので使って解いたのがこっちです

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(_=>_....)

みたいに書くのでそれがずっと頭に残ってました。だからどうとかではないんですが、頭はおかしくなりました。

何人かの方に気に入っていただけたようでとっても嬉しいです。いつか__で会話する日が来るといいですね(来ない)

まとめ

今回もとても楽しかったです!いつも大阪会場を用意してくださる方、主催の方々、ありがとうございました!(名前を出していいのかわからないのでぼかしています)