参加しました。今回は自宅からリモート参戦でした。
新生シェル芸Botがめちゃいい感じでしたね。整備ありがとうございます!!
この参加記では時間中の自分の解答と、解きなおしのPowerShell解をしたりしなかったりします。
Q1
以下のようなinput
ファイルがあります
a bb ccc dddd eeee fff gg h ii
このファイルから次のような出力を得るという問題
a bb a ccc a dddd eeee fff eeee gg h ii
ヤバそうな気がしますねえ。
cat Sh*/vol.65/input | stairl | awk 'NF!=1{print $1,$NF}'
stairl
はegzactのコマンドです。
stairl
を使うと以下のようになります
$ cat Sh*/vol.65/input | stairl a a bb a bb ccc a bb ccc dddd eeee eeee fff eeee fff gg h h ii
目的の出力得るためには、1列以上ある行について、各行の先頭と最後を選択すればよさそうです。なのであとはawk
でエイヤという感じにしました。
ところで、問題の制約としてtarr
などのツールやawk
のfor
を使わずにというのがあったのでそれにも挑戦してみます。
$ sel 1 2 1::2 1::3 -f ./Sh*/vol.65/input | \ juz 3 sed 's/ /\n/2' | \ awk 'NF!=1&&$1!=$2'
sel
の[n]:[m]:[k]
を使うと[n]
から[m]
まで[k]
個ごとに出力するクエリです。なので1::2
は1列目から2列ごとに出力するものです。この場合は以下のような出力になります
a bb a ccc a dddd eeee fff eeee gg eeee h ii h h
後は2個ずつ改行して必要なデータだけ取り出して終わりです。sed
は何回か繰り返す必要があるのですが、これにはjuzを使いました。便利です。
PowerShell解は↑で疲れたのでスキップです
Q2
input
内容を以下のように加工する問題
a dddd bb dddd ccc dddd eeee gg fff gg h ii
最後の列を毎列ごとに差し込むって感じですね。Q1で出た解答を参考にした感じです。解説は配信をご覧ください。
cat Sh*/vol.65/input | \ awk 'gsub(FS, FS$(NF)FS)' | \ sel :-2
こっちはPowerShell解を書きます
$ cat She*/*.65/input | %{ $x=($_ -split ' '); $_ -replace ' ',(" " + $x[-1] + " ") } | sel -- :-2 a dddd bb dddd ccc dddd eeee gg fff gg h ii
手法自体は同じです。書き方が違うというだけですね。awk
に慣れてると、ForEach-Object
では毎回split
しないといけないことがめんどくさく感じちゃいますね。なんかいい方法あったりするんでしょうか。
Q3
eeeeee
ファイルの内容をランレングス圧縮する問題です。
cat Sh*/vol.65/eeeeee | grep -oP '(.)\1*' | awk '$0=$1NF' FS= ORS=
grep
で文字ごとに行に分割します。あとはawk
で数えつつ連結するって感じです。awk
の部分はTLを見てて賢いな~と思ったのを参考にしています。
ところでjulia
にはランレングスするrle()
という関数があるようです。これでやってみます
cat ./Sh*/vol.65/e* | \ sel -d '' 0 | \ julia -E 'using StatsBase;rle(split(readline()))' | \ sel -d'[' 2: | \ tr '\]\)' \\n | \ tr -d ,\" | \ rs -T | \ tr -d \ \\n
出力の整形を結構頑張る必要がありますが、ロジックを自前実装する必要がないのがいいですね。
Q4
symbols
ファイルは以下のような内容です
a-> c-) g~> >-z-> )-d-) >~y~> )-e >-f >~i~> >~j
これを矢印の種類でまとめてくださいという問題。時間内に解けなかったので解説を参考にした解答を張っておきます。
cat Sh*/vol.65/sy* | \ sed -r 's/^([a-z])(.)(.)/\3\2\1\2\3/;s/../& /' | \ awk '{a[$1]=a[$1]$0}END{for(x in a) print a[x]}' | \ sel -D '' 2:
PowerShell解は以下です
$ cat She*/*.65/sy* | %{ @{k=$_ -replace '^[a-z](.)(.)','$2$1' -replace '^(..).+','$1';v=$_} } | group -Property k | %{ ($_.Group|%{$_.v}) -join '' } c-))-d-))-e a->>-z->>-f g~>>~y~>>~i~>>~j
左側の矢印をキーにGroup Byすればいいってことに気づいたので、PowerShellのGroup-Object
でやってみました。便利だ便利。こんな感じでGroup Byしてくれるコマンド、欲しくなりますね。
Q5
words
ファイルは以下のような内容です
ang ker ora ch pea eat spea nge rep le
1列目、2列目を組み替えて、意味のある単語にしてくださいという問題
$ join -j9 Sh*/vol.65/words{,} | awk '$0=$1$NF' | grep -x -f- /usr/share/dict/words
join -j9
とawk
ですべての組み合わせを列挙し、/usr/share/dict/words
に存在する単語を選ぶという感じです。
PowerShellはどうすればいいんだ…?
Q6
echo 焼肉定食
からはじめて総画数を計算するという問題。すごいぜ。
$ wget https://raw.githubusercontent.com/cjkvi/cjkvi-tables/master/joyo2010.txt $ echo 焼肉定食 | grep -o . | grep -f- ./joyo2010.txt | sel -a -- -3 | jq -s add
画数とかがまとまってるデータをwget
してきて、漢字をgrep
で検索。あとは該当のカラムを選んで足すという感じです。
PowerShell解は以下の通りです。
$ echo 焼肉定食 | %{ $_ -split '' } | ?{ $_ } | %{ ((sls $_ .\joyo2010.txt) -split '\s')[2] } | measure -Sum | %{$_.Sum}
echo 焼肉定食
で始めることを意識してこんな感じに仕上げてみました。大体のことは組み込みでできますね。
Q7
kim
ファイルの内容から総画数が素数な行を取り出す問題。
$ cat Sh*/vol.65/kim | \ while read N; do echo $N $(echo $N | grep -o . | grep -f- ./joyo2010.txt| sel -a -- -3 | jq -s add|factor); done | \ awk 'NF==3{print $1}'
Q6の解答を拡張しただけですね。
LT
今回はLTさせていただきました!
内容としては呪符式高速詠唱シェル芸の続きです。読み取りに使うOCRを複数個にすることで誤認識を減らそうというアイデアを実装したものになります。
最後のライブコーディングでも正しく読み取れたので良かったです!
聞いてくださった方ありがとうございました!
おわり
最近はjulia
やegzact
といった便利なツールを学んだことで、複雑なことを短いコマンドでできるようになりました。それもいいんですが、コマンドを組み合わせることと情報を足して処理しやすくすることも大切だなと感じる問題が多かったです。どっちもできるようになりたいですね。
今回も準備・運営ありがとうございました!
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄| | 終 | | 制作・著作 | |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ | | xztaityozx | |_________| ∧∧ || ( ゚д゚)|| / づΦ