【問題と解答】jus共催 jus共催 第45回せんせいがAIとかしんぎゅらりてぃーってタイトルにつけとくとべんきょうかいにひとがあつまるよっていってたかんけいないけどシェル芸勉強会
Sat Dec 28 16:34:39 JST 2019 (modified: Sat Dec 28 16:34:39 JST 2019)
views: 2974, keywords:プログラミング,勉強会,シェル芸,シェル芸勉強会 この記事は最終更新日が4年以上前のものです。
- 問題で使われているデータファイルはGitHubにあります。クローンは以下のようにお願いします。
git clone https://github.com/ryuichiueda/ShellGeiData.git $
- 環境: 解答例はUbuntu Linux 18.04 で作成。Macの場合はcoreutilsをインストールすると、GNUのコマンドが使えます。BSD系の人は玄人なので各自対応のこと。
Q1
次のCSVファイル(Shift JIS)には、日ごとトマト、バナナ、ピーマンの売れた個数が書かれています。トマト、バナナ、ピーマンについて、記録されている最後の日の日付と個数を出力してください。
$ cat data.csv
2019/12/6,?g?}?g,3??
2019/11/23,?o?i?i,2??
2019/11/8,?s?[?}??,31??
2019/12/30,?g?}?g,4??
2019/11/2,?g?}?g,1??
2019/12/9,?o?i?i,4??
2019/12/21,?o?i?i,5??
2019/11/21,?s?[?}??,32??
2019/12/1,?g?}?g,7??
解答例
$ cat data.csv | nkf -wLux | tr , " " | sed 's;/\(.\) ;/0\1 ;'
| sort -k2,2 -k1,1r | awk '{print $1,$3,$2}' | uniq -f 2
2019/12/30 4個 トマト
2019/12/21 5個 バナナ
2019/11/21 32個 ピーマン
Q2
日経のこのページ(https://indexes.nikkei.co.jp/nkave/index?type=download ) から日経平均株価の日次データをダウンロードして、毎月の終値の最高値と最安値を出力してください。
解答例
$ nkf nikkei_stock_average_daily_jp.csv | awk -F , '{print $1,$2}'
| tr -d '"' | grep ^2 | sed 's;/.. ; ;' | awk '{print $2,$1}'
| sort -k2,2 -k1,1n | pee 'uniq -f 1' 'tac | uniq -f 1'
| sort -k2,2 | xargs -n 4 | awk '{print $2, ($1>$3) ? $1" "$3:$3" "$1}'
2016/01 18450.98 16017.26
2016/02 17865.23 14952.61
2016/03 17233.75 16085.51
2016/04 17572.49 15715.36
2016/05 17234.98 16106.72
2016/06 16955.73 14952.02
2016/07 16810.22 15106.98
・・・
Q3
ファイルflag_a, flag_b
には国旗が記録されていますが、何箇所かflag_a
とflag_b
で違いがあります。左上から数えて何番目の国旗が異なるかを出力してください(「何行目の何番目」ではなくて、1行目からの通算の個数で答えてください)。
$ head flags_*
==> flags_a <==
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇨🇳🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
==> flags_b <==
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵
🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇰🇵🇮🇲🇰🇵
解答例
$ paste <(grep -o .. flags_a) <(grep -o .. flags_b) | awk '$1!=$2{print NR}'
39
65
Q4
次のnabe
ファイルについて、一文字ごとに改行を入れてください。
$ cat nabe
部邊邊󠄓邊󠄓邉邉󠄊邉󠄂邊邊󠄓邊󠄓邉邉󠄆辺邉󠄄邊辺󠄀邉邉󠄈邉󠄊邉󠄌邊邊󠄓邊󠄓邉邉󠄆邉󠄊邊邊󠄓邊󠄓邉邉󠄆邉󠄘邊邊󠄓邊󠄓邉邉󠄆邉󠄕邊邊󠄓邊󠄓邉邉󠄊邉󠄓部
$ (ワンライナー)
部
邊
邊
邊
邉
邉
・・・
解答例
$ cat nabe | sed -r 's/[部辺邊邉]([^部辺邊邉])*/\n&/g' | tail -n +2
Q5
次のメッセージから、回文になっている部分をすべて抜き出してください。ある回文の中にある部分的な回文(例: 「きつつき」の場合「つつ」)を含んでも構いません。
$ cat message
きつつきとまとへんたいとまとたけやぶやけないたけやぶやけたでんぱゆんゆんおかしがすきすきすがしかお
解答例
$ cat message | awk '{for(i=1;i<=length($0);i++)print substr($0,1,i)}' | awk '{for(i=1;i<=length($0);i++)print substr($0,i)}' | ruby -anle 'puts $_ + " " + $_.reverse' | awk '$1==$2&&length($1)>1{print $1}' | sort -u
Q6
Q5の答えがmessage.ans
に入っています。この中から、部分的な回文を削除してください。
$ cat message.ans
つつ
きすき
すきす
とまと
やぶや
ゆんゆ
んゆん
きつつき
けやぶやけ
すきすきす
がすきすきすが
たけやぶやけた
しがすきすきすがし
かしがすきすきすがしか
おかしがすきすきすがしかお
解答例
$ cat message.ans | while read a ; do grep -o $a message.ans ; done | sort | uniq -u
おかしがすきすきすがしかお
きつつき
たけやぶやけた
とまと
ゆんゆ
んゆん
Q7
x/y
が割り切れない自然数の組x,y (x<y)
について、echo x y
からはじめて、計算結果(小数)を延々と出力するワンライナーを考えてください。
解答例
$ echo 1 7 | awk '{print "0.";while(1){print int($1*10/$2);$1=($1*10)%$2}}' | tr -d \\n
Q8
Q7で出力した小数は、いつか同じ数字の並びの繰り返しになります。繰り返しになったら小数の出力をてきとうなところで打ち切り、小数何桁目から何個の数字の繰り返しになるかを後ろにつけてください。(無限の桁まで対応する必要はありません。)
- 例
1/3 -> 0.3 1 1
1/7 -> 0.142857142857 1 6
解答例
$ echo 1 7 | awk '{print "0.";while(1){printf int($1*10/$2);$1=($1*10)%$2;print " "$1}}' | awk '{b[NR-1]=$2;for(i=1;i<NR-1;i++){if(b[i]==b[NR-1]){print a, i,NR-2;exit}}a=a$1}'
0.142857 1 6