「第44回シェル芸勉強会:福岡サテライト」レポート
実に1年ぶり!シェル芸勉強会の福岡サテライトを開催いたしました。今回の会場は、福岡市エンジニアカフェのメインホールを使わせていただきました。参加者は全部で5人で、初参加者は3人でした。会場が想像以上に広くて立派で驚きました。福岡サテライトの規模的には、ちょっと立派過ぎて気が引けちゃう感もありました。
勉強会の情報
主催者上田さんが公開されているリンク集をご覧ください。
会場
今回は福岡市の天神・赤煉瓦文化館内にある「エンジニアカフェ」のメインホールを始めて利用しました。 イベントの会場として利用するには、初回はコミュニティマネージャの方と対面で面談が必要です。 各施設・設備は無料で利用可能。メインホールではプロジェクターやインターネット接続が利用出来ます。プロジェクターはRGBやHDMI接続以外に、AirPlayがWi-Fi(AppleTV経由)で使えるのがすごく便利だったですね。
twitter.com会場到着 pic.twitter.com/4XDDEqjL4H
— ぱぴろんちゃん😱🙀 (@papiron) 2019年10月26日
twitter.com会場内はこんな感じ。電源も使いやすい #シェル芸 #福岡 pic.twitter.com/uwn9G6LNtb
— ぱぴろんちゃん😱🙀 (@papiron) 2019年10月26日
twitter.com#シェル芸 #福岡 #engineercafe 会場準備出来ました。 pic.twitter.com/LmclDKwiK8
— ぱぴろんちゃん😱🙀 (@papiron) 2019年10月26日
スライド資料
どちらも話す時間が無かったのだが、ここに晒しておきます。
午前の部
午前中はぷるさんによるJavaScript入門でした。解説を聞きながら、node
はNode.jsのREPL環境を試してみました。
JavaScripのObjectコピーは参照渡しなのよ。値渡しにするには{...Obj}
みたいな書き方するらしいのよ。
$ node > obj1 = {key:1} { key: 1 } > obj2 = obj1 { key: 1 } > obj3 = {...obj1} { key: 1 } > obj1.key = 2 2 > obj1 { key: 2 } > obj2 { key: 2 } > obj3 { key: 1 } >
まあでもRubyのハッシュも参照渡しだったわね。pry
はRubyのREPL環境。
$ pry [1] pry(main)> hash1 = {:key=>1} => {:key=>1} [2] pry(main)> hash2 = hash1 => {:key=>1} [3] pry(main)> hash1[:key] = 2 => 2 [4] pry(main)> hash1 => {:key=>2} [5] pry(main)> hash2 => {:key=>2} [6] pry(main)>
午後の部
今回の問題は、コマンドの組み合わせというよりawkでゴリゴリ頑張る系らしいです。
自分なりに考えた解答例を記載しました。今回は非常に頭を使う問題だったと思います。最初は「数独」を理解していなかったので、問題の意図が分からず置いてけぼりになりかけました。
Q1
第3フィールド以外はとりあえず無視して、行、列、値だけなら簡単な気がします。FS=
は列(フィールド)の区切り文字を空文字に指定、要するに1文字ずつ区切るということでした。オプションで-F ''
と指定しても同様です。
$ cat sudoku | awk '{for(i=1;i<=NF;i++){print NR-1,i-1,$i}}' FS= 0 0 5 0 1 3 0 2 * 0 3 *
次に第3フィールドを考えるのですが、この後がわかりませんでした。出題者上田さんの解答例では、3つずつ同じ物が続くということは、3で割って切り捨てれば良いという考え方でした。
Q2
ギブアップでした!
Q3
チョット要領が悪い解答を晒しておきます。
$ cat b | cut -c9- | tr -d ' ' | while read s; do [ -n "$s" ] && echo 123456789 | tr -d $s || echo; done | sed 's/./& /g' | paste -d ' ' a - | sed 's/ *$//'
ポイントはこちらです。例えば「1、3、5、6」以外の数字は何になるかはtr
コマンドを使って処理しています。
$ echo 123456789 | tr -d 1356 24789
Q4
前半はデータを行列のマトリックスに戻す問題。ただし下記のような行は値が確定しています(入る数字の候補が1つに絞られている)。
... 4 4 4 * 5 ... 6 5 7 * 7
値が確定している行は列数が5個になっているのを利用した解答がこちらです。パターンがNF==5
とNF!=5
の2種類出現します。
$ cat c | awk 'NF==5{a[$1+1,$2+1]=$5}NF!=5{a[$1+1,$2+1]=$4}END{for(i=1;i<=9;i++){for(j=1;j<=9;j++){printf a[i,j]}print ""}}' 53**7**** 6**195*** *98****6* 8***6***3 4**853**1 7***2***6 *6***7284 ***419*35 ****8**79
ナンバープレースの問題は解けませんでした。
Q5
積分は要するに細かい長方形の足し算という雑な解答がこちらです。もっと精度を上げるには、出題者上田さんの解答のように台形の足し算にしましょう。
$ seq 0 0.001 0.5 | awk '{printf "%.20f\n",log((cos($1)))*0.001}' | numsum -0.0214458744608356
seq
コマンドは引数を3つ指定すると、第二引数が増分になります。
$ seq 0 0.001 0.5 0.000 0.001 0.002 ... 0.498 0.499 0.500
numsum
コマンドは、数値のリストを足し算します。(Perl実装なので大量のデータは処理がやや遅いです)
$ seq 1 3 | numsum 6
Q6
色々とスマートな解答が出ていました。自分なりの解答がこちらです。
まずspeechファイルで空行の行番号を取り出し、speech2ファイルの行頭に順次付加します。
$ cat speech | awk 'length==0{printf "%02d\n",NR}' | paste -d' ' - speech2 03 んこも休み休み言え 04 春はあけぼの。夏は 07 ビも無ェ、うんこも 09 かた見だごとア無ェ 12 した。あなたのうん 13 こですお前それうん 14 こでも同じ事言えん
speechファイルには、行頭に行番号を付加します。
$ awk '{printf "%02d %s\n",NR,$0}' speech 01 このうんこを作った 02 のは誰だあっ!!う 03 04 05 夜。秋は夕暮れ。冬 06 はうんこハァ テレ 07 08 無ェ、生まれてこの 09 10 やつはとんでもない 11 ものを盗んでいきま 12 13 14 15 の?疲れからか、
後はこの2つのデータをOUTER JOINします。行番号はゼロ埋めした固定長にしていますが、これはjoin
コマンドで結合する際にキー列が辞書順に並んでいる必要があるためです。
$ cat speech | awk 'length==0{printf "%02d\n",NR}' | paste -d' ' - speech2 | join -a 2 - <(awk '{printf "%02d %s\n",NR,$0}' speech) 01 このうんこを作った 02 のは誰だあっ!!う 03 んこも休み休み言え 04 春はあけぼの。夏は 05 夜。秋は夕暮れ。冬 06 はうんこハァ テレ 07 ビも無ェ、うんこも 08 無ェ、生まれてこの 09 かた見だごとア無ェ 10 やつはとんでもない 11 ものを盗んでいきま 12 した。あなたのうん 13 こですお前それうん 14 こでも同じ事言えん 15 の?疲れからか、
Q7
RSA暗号に関する問題でした。
小問1
巨大な整数の乗算と剰余計算出来るか?が壁。bc
コマンドの力を利用した解答がこちらです。
まず計算する式の文字列を作成します。
$ cat message | tr ' ' '\n' | sed 's/$/^200%437/' 262^200%437 325^200%437 122^200%437 80^200%437 266^200%437 406^200%437 163^200%437 89^200%437 325^200%437 89^200%437 326^200%437
後はbc
コマンドに食わせ、xargs
で横に並べて完成です。
$ cat message | tr ' ' '\n' | sed 's/$/^200%437/' | bc | xargs 35 308 26 282 399 87 349 55 308 55 85
awk
で計算するにはコツが必要で、GNUのMPFR、MPライブラリが必要です。
#数が大きすぎて桁が溢れてしまう $ awk 'BEGIN{print 262^200%437}' -nan # -MオプションでGNUのMPFR、MPライブラリを有効にする。 $ awk -M 'BEGIN{print 262^200%437}' 35
GNUのMPFR、MPライブラリを利用するには、コンパイル時に組み込まれている必要があります。
--version
オプションで確認出来ます。
$ awk --version GNU Awk 4.1.4, API: 1.1 (GNU MPFR 4.0.1, GNU MP 6.1.2) ...
小問2
ギブアップ!
小問3
ギブアップ!
終わりに
久しぶりに福岡サテライトを開催しましたが、今回は純粋に頭を使う問題が多くて初参加者へのフォローがあまり出来なかったように思います。出来る限りはサポート頑張ってみましたが、福岡サテライト参加者の皆様申し訳ありませんでした。問題の難易度が高くて参加者の方は大変だと思いますが、問題に食らいつくガッツは鍛えられるのではないかと思います。