2016年5月27日金曜日

第22回ゴールデンウィークの存在疑惑シェル芸勉強会 第1問

相変わらずシェル芸勉強会には参加できなかったので後日解いてみました。とりあえず第一問です。問題と解答はここにあります。

第1問

最初の解答

cat a | sort -n | pee 'wc -l' cat | awk 'NR==1{n=$1}(NR-1)==int(n/2)+1||(NR-!(n%2))==int(n/2){a[NR-1]=$1}END{if(n%2){print a[int(n/2)+1]} else {print (a[n/2]+a[n/2+1])/2}}'
view raw gistfile1.txt hosted with ❤ by GitHub

だいぶ狂った解答です。最初に全体の行数をwcで数えてそこからAWKでこねこねしてます。

場合分けのない解法

ここ
データ数が偶数と奇数の時で場合分けが必要で面倒くさいです。(場合分けのない方法絶賛募集中。)
と書いてあったので場合分けをしない解答も考えました。
sort -n | awk '{a[NR]=$1}END{for(i=1;i<=NR;i++)print(a[i]-a[NR-i+1])*(a[i]-a[NR-i+1]),(a[i]+a[NR-i+1])/2}' | sort -n | head -n 1 | cut -d " " -f 2
view raw gistfile1.txt hosted with ❤ by GitHub

気分がわかるようにAWKで一気に書かれている部分をほぐして説明します。 入力が

3.4
13
42
-4
-5
の時は sortして
-5
-4
3.4
13
42
反転したものと横に並べて
-5 42
-4 13
3.4 3.4
13 -4
42 -5
差の2乗と平均を出して
2209 18.5
289 4.5
0 3.4
289 4.5
2209 18.5
sortしたときの第二カラムの値が中央値です。
0 3.4
289 4.5
289 4.5
2209 18.5
2209 18.5

反転したものと横に並べる周りが汚い感じになっちゃってます。もう少し何とかならないものでしょうか(tukubaiとか?)