たいちょーの雑記

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

VSCodeからあかりちゃんに喋ってもらいたかったから拡張機能作った

VSCodeから棒読みちゃんに喋ってもらう拡張機能作りました

作りました

動機

xztaityozx.hatenablog.com
xztaityozx.hatenablog.com

これまで作ってきた拡張機能のおかげで今PC上で生活するうちの半分ぐらいをあかりちゃんとともに過ごしているわけですが、正直まだちょっと足りないので今度はVSCode拡張機能に挑戦しました。

VSCBouyomi

例によって拡張機能越しに棒読みちゃんを操作する系です。 inst1

特に設定なしにインストールするだけで始められます。

使い方

インストールするとデフォルトだとCtrl+Shift+Pに割り当ててあるコマンドパレットから以下のコマンドが使えます。一緒に表記してある内部コマンドを使えば任意のキーバインドも設定できます。たぶん

  • VSCBouyomi : Talk : 読み上げ
    • 内部コマンド : vscbouyomi.talk
  • VSCBouyomi : Skip : 読み上げのスキップ
    • 内部コマンド : vscbouyomi.skip
  • VSCBouyomi : Pause : 読み上げの一時停止
    • 内部コマンド : vscbouyomi.pause
  • VSCBouyomi : Resume : 読み上げの再開
    • 内部コマンド : vscbouyomi.resume

usage2
vscbouyomi.talkを実行すると文章全体を読み上げます。このとき文字列が選択してあるならそこだけを読み上げます。

設定

大した設定もないですが
詳しい値などは棒読みちゃん付属のSampleSrc.txtをお読みください

項目 説明
vscbouyomi.encoding utf-8 or shift-jis or unicode 読み上げる文章のエンコーディングです
vscbouyomi.delimitor 文字列のリスト 文章の区切りを指定できます
vscbouyomi.skipblank true or false trueのとき空白行を飛ばします
vscbouyomi.speed 数値 棒読みちゃんの読み上げ速度です
vscbouyomi.tone 数値 棒読みちゃんの音程です
vscbouyomi.voice 数値 棒読みちゃんの声です
vscbouyomi.volume 数値 棒読みちゃんの音量です

既知のバグ

読み上げの順番がたまにおかしくなる。重大なバグすぎる

ブラウザからあかりちゃんに喋ってほしかったので拡張機能作った

ブラウザで選択してる文字列を棒読みちゃんに送るWebExtentionsを作った

作りました

動機

ネットサーフィンをしていると読みたいな~と思う記事に出会うことがあります。しかし長文を「読む」というのは中々パワーが要るため、僕はVOICEROIDのエディタへ読みたい部分をコピペして読み上げをさせていました。

この手順は例えば

  1. 記事を選択する
  2. コピーする
  3. VOICEROIDへウィンドウを切り替える
  4. 貼り付ける
  5. 再生を押す
  6. 聞く
  7. あかりちゃんかわいい

となりますが、手順7へたどり着くのにかなり手を動かさないといけないので非常に面倒です。しかしブラウザからVOICEROIDを操作するのは大変です。なのでブラウザから棒読みちゃんを操作して間接的にあかりちゃんを操作することを目指します。

棒読みちゃんからVOICEROIDを操作するのは棒読みちゃんプラグインであるVoiceroid Talk Plusを利用します。

ch.nicovideo.jp

インストール

BS2B

GitHubからクローンして手元のブラウザにインストールする。もしくはFirefoxならFirefox Add-onsで公開しているのでそこからインストールできます。

棒読みちゃんWebSocketサーバープラグイン

GitHubからクローンしてきてPlugin_WebSocket.dll棒読みちゃんと同じディレクトリにコピーしてください。

BS2B

ラウザーで んたくしてる文字列を 読みちゃんに送る やつBS2Bという名前にしました。意味がわからない

ブラウザで選択したところを棒読みちゃんに送るやつ – Firefox 向けアドオン

github.com

拡張機能を導入すると、ブラウザのメニューバーにマイクのアイコンが追加されます。このアイコンをクリックするとポップアップが表示されます。ここから棒読みちゃんへリクエストを送ることができるようになっています。

構成はこんな感じです。

FirefoxGoogle Chrome、MS EdgeなどWebExtentionsに対応しているブラウザにインストールされたBS2BはWebSocketを介して棒読みちゃんに読み上げや一時停止、再開などのリクエストを送ります。そこからVoiceroid Talk PlusがVOICEROIDのエディタに文字列を渡し、あかりちゃんが読み上げます。かわいい

ただし棒読みちゃんはWebSocketに対応していないので、自前でWebSocketサーバーをプラグインとして用意する必要があります。今回はそれも用意しました。

github.com

といってもモノ自体は先駆者の方のForkになります。BS2Bが扱いやすいように機能を追加しています。

使い方

  1. メニューバーのボタン
    • クリックするとこのポップアップがでます。ポップアップが開かれたとき選択している文字列がテキストボックスに 追加 されます。
  2. 設定チェックボックス
    • テキストを保持する : ポップアップを閉じてもテキストボックスを保持します。
    • 送った後にテキストをリセットする : Sendボタンを押した後テキストボックスがクリアされます。
  3. テキストボックス
    • ポップアップ起動時に選択されていた文字列が表示されます。編集可能なので送る前に適当に調整すればいいと思います
    • ただし棒読みちゃんへは改行コードで分割され1行単位で送られます。
    • さらに1行の長さがある程度長いとSkipされてしまいます。
  4. ステータス
    • BS2Bのステータスを簡易的に表示します。
  5. Skipボタン
  6. Pauseボタン
  7. Resumeボタン
  8. Resetボタン
    • テキストボックスをリセットします。
  9. Appendボタン
    • 選択されているテキストをテキストボックスに 追加 します。
  10. Sendボタン

雑感

WebExtentionsとかJSとかの勉強がてらに不便を1つ解消しました。これでブラウザを開いていてもあかりちゃんと一緒に居れますね!(うれしい)

今思えば適当にキーバインドとかを設定してもよかったかもしれないですね。ボタンが遠い。

参考

第37回シェル芸勉強会@大阪サテライトに参加しました

(^o^)/

(^-^)

午前の部

鳥海さんによる文字コードについての講義。難読化シェル芸のネタが転がっているかも知れないので楽しみでした。講義中は2重forのシェル芸がいきなり出てきたりかなり激しめでしたね。

今回の講義で一番印象に残ったのはiconvでcp930とcp939を行ったり来たりするところでした。例えば

$ echo スリスリ| iconv -f utf-8 -t cp930 | iconv -f cp939 -t utf-8
ヌメヌメ

というふうにテーブルを変えることで別の意味に変換できたりします

これは難読化に簡単に応用できて

$ echo オイヤカ | iconv -f utf-8 -t cp939 | iconv -f cp930 -t utf-8 | bash
201891日 土曜日 16:08:40 JST

オイヤカという文字列をdateに変換できます。もう少し何か工夫すれば複雑な難読化シェル芸ができるかも知れませんね

午後の部

今回も午後はヤバイ問題をいっぱいときました。
開始宣言が「地獄の始まり」とのことだったのでやる前からフラフラでした 問題はこちら

Q1

FizzBuzzを表示するgifアニメーションを作りなさい。

seq 100 | sed -e '3~3cFizz' -e '5~5cBuzz' | sed '15~15cFizzBuzz' | animation

animationはシェル芸botに実装されているgifアニメを作ってくれるコマンドです。ソースを読むと何をしているかわかります

Q2

プロヴィデンスの目のAAを作りなさい。

seq 4|awk '{for(i=0;i<4-$1;i++)printf " ";printf "/";for(i=0;i<$1*2-2;i++)printf " ";print "\\"}'|cat - <(echo  ̄ ̄ ̄ ̄)| sed 's|/    \\|/ 目 \\|'  

愚直にawkforを回します。特筆するところはないですね

Twitterでみた東映版が面白かったので自分のやつでもやってみました。

seq 5|awk '{for(i=0;i<5-$1;i++)printf " ";printf "/";for(i=0;i<$1*2-2;i++)printf " ";print "\\"}'|cat - <(echo  ̄ ̄ ̄ ̄ ̄)| sed '3s|    | 東 |;4s|    |  映|'

Q3

以下の条件を満たす数字を全部出力しなさい

  • 3桁の数
  • 桁和が15
  • 0を含まない
  • 同じ数字を含まない

競プロとかに出てきそうな問題だと思いました

seq -w 999|awk '{print $1,$1}'| sed -E 's/(.)(.)(.)/echo $((\1+\2+\3))/e'| grep -v 0|awk '$1==15{print $2}' | grep '\(.\).*\1' -v | xargs

最初のsedで桁和を計算しています。その後0を含む行をgrepで排除し、awkで桁和が一致する数をとりだした後、grepで同じ文字が存在しない行だけ取り出して終わります。
最後のgrepカンニングしました・・・。聞けば前回やっていたそうなので身についてないな〜と反省しました。精進精進

Q4

役満を出力してください
麻雀はわからないので役満もわからないのですがとりあえず例になっていたのを真似ました。

cat <(yes "+--+"|head -n14|xargs) <(echo -e "\n\n\n\n\n\n西\n西\n西\n\n\n\n \n "|sed 's/./|&|/g'|xargs) <(yes "+--+"|head -n14|xargs)

牌をAAで表現しました。やってる事自体は全然難しくないようですが、想定解とは全然違ったみたいですね・・・

Q5

    山    
    山    
    山    
山  山  山
山山山山山
          
⽥⽥⽥⽥⽥
⽥  ⽥  ⽥
⽥⽥⽥⽥⽥
⽥  ⽥  ⽥
⽥⽥⽥⽥⽥

を出力してください。なんやねんこれ・・・

echo -n "1f8b080028288a5b00037bdcd0f0b8a1e1e9c68d8fc18cc778b910069c44
43c85a80e8d1dea568082288550abf2c00a1eea7afa5000000" | xxd -ps -r | gunzip|grep -o .|xargs -n5|tr -d ' '

難読化すればするほど良いですとのことだったので gunzip を使ってみました。全角のスペースで埋めて gzip 圧縮したものを gunzip に通して xargs でまとめただけですね

Q6

  山  
  田  
  山  
山 田 山
田山田山田
     
田山田山田
山 田 山
田山田山田
山 田 山
田山田山田

この出力を得てください。アハハ

echo -n "1f8b08009c298a5b00037bdcd0f0b8a1e1e9c68d8fc10c087a3e65033217
2e0b614064816c20039944d602448ff62e058a23931041885efcb21033e1                                           
b200ebf8a623a5000000
" | xxd -ps -r | gunzip|grep -o .|xargs -n5|tr -d ' '

さっきの解答の入力を変えただけです。それだけだと面白くないので以下の難読化も試してみました。

eval $(echo -n "1f8b0800d52a8a5b00034b4dcec85778dcd000444f376e843020e8f9940d
c85cb82c84019105b2810c6412590b103ddabb14288e4c4204217af1cb42
cc84cbd6a417a51628e8e62be8d5542416a5172be8e699d6941429e8a628
a82ba8030053a9f2f8c8000000"|xxd -ps -r|gunzip)

これも gunzip を使ったやつです。これは僕が少し前にLTしたやつですね。

www.slideshare.net

eval を外すとどうなるかと言うと

$ echo -n "1f8b0800d52a8a5b00034b4dcec85778dcd000444f376e843020e8f9940d
c85cb82c84019105b2810c6412590b103ddabb14288e4c4204217af1cb42
cc84cbd6a417a51628e8e62be8d5542416a5172be8e699d6941429e8a628
a82ba8030053a9f2f8c8000000
echo   山    田    山  山 田 山田山田山田     ⽥山⽥山⽥山 ⽥ 山⽥山⽥山⽥山 ⽥ 山田山⽥山⽥|grep -o
 .|xargs -n5|tr -d ' '

解答を生成するワンライナーが仕込まれています。最近の難読化シェル芸の発展を見るとちょっとおとなし目な難読化ですね

Q7

matsuya コマンドで生成されたメニューをひらがなに変換して toilet に通した後、1行に連結し画像に落とし込む問題。手順が多すぎる。

途中までしか出来ませんでした・・・1行にまとめるところが出来なかった。

$ matsuya|mecab| awk -F, '{print $1,$6}'|awk 'NF==3{print $3=="*"?$1:$3}'|xargs|toilet

Q8

matsuya コマンドの出力を使って以下のようにしてください
例) 鉄皿鶏のチリソース定食だったとき

鉄皿鶏のチリソース定食
皿         定
鶏         ス
の         ー
チ         ソ
リ         リ
ソ         チ
ー         の
ス         鶏
定         皿
食定スーソリチの鶏皿鉄

上下左右が逆になっていることが難しいポイントですね。

c="$(matsuya)";cat <(echo $c) <(paste <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .) <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .|tac)) <(echo $c|rev)|column -t|sed 's/    \(.\)$/\1/g'

ちょっとセコいんですが変数にメニューを保存しておきます。あとは天井と床、左右の壁を作って cat に順番に流し込みます。
面倒なのは左右の壁だけなので、そこだけ解説します。
1文字目と最後の文字を削って、縦に並べて paste で連結します。天井、床と合わせてこれを column で幅を取るといい感じに並びます。

$ c="$(matsuya)";cat <(echo $c) <(paste <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .) <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .|tac)) <(echo $c|rev)
きつねうどん
つ            ど
ね            う
う            ね
ど            つ
んどうねつき

このスキマはちょうど半角スペース4つ分なので sed で削って終わりですね

awkの中でpipe

この問題の解答のなかでawkの中でコマンドを実行できるというのを知りました。すげーっすねこれ・・・

$ echo abc | awk '{print | "rev"}'
cba

LT

今回は新しい難読化シェル芸についてでは無いですが、宣伝をしようと思いまして発表させていただきました。
www.slideshare.net

cdx という cd コマンドのラッパーを作ったのでその宣伝をしました。因みにスライド内で言っている海外は体調不良で断念して今布団の上でコレを書いています。しんどいわホンマ

そんなことより cdx をよろしくお願いたします。

github.com
xztaityozx.hatenablog.com

終わりに

今回も午前午後、LT大会ぜんぶとても楽しかったです。皆様ありがとうございました!!

Goが面白いのでまたcdx作った

cdx

github.com

cdx は僕が一人でメンテしてる cd コマンドのラッパーです。この手のツールでよく使われているのは、enhancdzなどがあります。

github.com

github.com

とくにenhancdは非常に強力なツールで、利用している方も多いと思います。

cdxではCustomSourceという設定項目を用意しました。これを利用することでenhancdの持つような機能はユーザー側が設定として与えることが出来ます。そのかわりcdxは僕が素の状態である程度使えるような機能だけを実装したものになります。

要求環境

  • Go lang (v1.10.2 以上)
    • 実装にはGoを使いました。最近はじめて面白いなと思いました。CLIツールを作るならGoはいい感じですね
  • bash or zsh
    • fishは対応していません
  • fzfやpecoみたいなFuzzy-Finder

インストール

  1. go get するか、GitHubのReleaseページからバイナリをダウンロードしてパスの通ったところに置いてください
$ go get github.com/xztaityozx/go-cdx
  1. お好みのFuzzy-Finderを用意します。個人的には fzfがすきです。 fzy と言うやつもいいらしいですね

github.com

github.com

  1. コンフィグを書いて置きます
$ mkdir -p ~/.config/go-cdx
$ cat << EOF > ~/.config/go-cdx/.go-cdx.json
{
  "HistoryFile": "~/.config/go-cdx/history.json",
  "BookMarkFile":"~/.config/go-cdx/bookmark.json",
  "Command":"pushd",
  "NoOutput":true,
  "Make":false,
  "CustomSource":[],
  "FuzzyFinder":{
    "CommandPath":"選んだFuzzy-Finder",
    "Options":[]
  },
  "BinaryPath":"go-cdxへの絶対パス。go getした場合は消してOK"
}
EOF
$ vim ~/.config/go-cdx/.go-cdx.json # 好きなように設定してください

設定値はGitHubのREADMEに書いてあるのでそちらを見てください

  1. cdx をロードします。
# cdxをロード
$ eval "$(go-cdx --init)"
# シェル起動時に自動でロードするならrcに記述すればOK
$ echo 'eval "$(go-cdx --init)"' >> ~/.zshrc # or ~/.bashrc

使い方

cdx [-A,--action [act]|
     --add|
     -b,--bookmark|
     --config [configFile]|
     --cs-list|
     -c,--custom [name]|
     --help|
     -h,--history|
     --init|
     --make|
     --no-output|
     -p,--popd|
     -v,--version] [PATH]

基本はcdコマンドと同じように使います

$ cdx ~/      # change to home
$ cdx ~/Utils # change to ~/Utils

-A,--action [act]

このオプションでは移動した後にそのディレクトリで実行するコマンドを指定できます

$ cdx ~/Utils --action "ls"
go-cdx
go-cdx.v1.0.13
go-cdx.v1.0.13.tar.gz
...
$ pwd
/home/xztaityozx/Utils

コマンドはbash -cに渡されて実行されることに注意してください

--add

ブックマークにカレントディレクトリを追加します。重複のチェックをしないので注意してください

-b,--bookmark

bookmarkからFuzzy-Finderを使って1つ選択し、cdします。

$ cdx -b
>
  3/3
> [   3] /path/to/hoge
  [   2] /path/to/fuga
  [   1] /path/to/foo

--config [configFile]

デフォルトのコンフィグの代わりになるコンフィグファイルを指定できます。デフォルトは~/.config/go-cdx/.go-cdx.jsonです

--cs-list

後に説明するCustomSourceからのcdの一覧を表示して終了します

-c,--custom [name]

Goでcdxを書き直すにあたって、追加した目玉機能です

cdxは複雑な機能を単体で持ちませんが、代わりにユーザーが機能を自由に追加することが出来ます。これをCustomSourceとよんでいます

CustomSource は、その 名前Fuzzy-Finderに与える入力 のペアで構成されます。

{
    "CustomSource":[
        {
            "Name":"g",
            "Command":"ghq list | xargs -n1 -I@ echo 'echo -e \"$(basename @) $(ghq root)/@\"'|bash|column -t"
        },
    ]
}

この例では、 ghq listで表示されるリポジトリ一覧から1つ選んでcdするgという名前の機能を追加しています

# Fuzzy-Finderに与える入力
$ ghq list | xargs -n1 -I@ echo 'echo -e \"$(basename @) $(ghq root)/@\"'|bash|column -t
"Contest                        /home/xztaityozx/.ghq/github.com/xztaityozx/Contest"
"cdx                            /home/xztaityozx/.ghq/github.com/xztaityozx/cdx"
"dotfiles                       /home/xztaityozx/.ghq/github.com/xztaityozx/dotfiles"
"nandokuka                      /home/xztaityozx/.ghq/github.com/xztaityozx/nandokuka"
"yov                            /home/xztaityozx/.ghq/github.com/xztaityozx/yov"
# cdx のCustomSource gを使ってみる
$ cdx -c g
>
  19/19
> Contest                        /home/xztaityozx/.ghq/github.com/xztaityozx/Contest
  cdx                            /home/xztaityozx/.ghq/github.com/xztaityozx/cdx
  dotfiles                       /home/xztaityozx/.ghq/github.com/xztaityozx/dotfiles
  nandokuka                      /home/xztaityozx/.ghq/github.com/xztaityozx/nandokuka
  yov                            /home/xztaityozx/.ghq/github.com/xztaityozx/yov

この機能を使って、Fuzzy-Finderで選択された行のいちばん後ろのカラムが、移動先のパスとして選択されることに注意してください

CustomSourceでオレオレcdxを作ることが出来ます

--help

ヘルプを出力して終了します

-h,--history

履歴をFuzzy-Finderで選択してcdします。ログアウトしても履歴はリセットされません

--init

cdxをロードするときにのみ使います

--make

移動しようとする先が存在しないディレクトリだった場合、作成するか訪ねます。yesと答えた場合のみ、ディレクトリを作成しcdします

--no-output

cdxからの出力を無効化します。Fuzzy-Finderや--action出力は表示されます。

-p,--popd

popdを実行して終了します

-v,--version

バージョン情報を出力して終了します

終わり

cdx をよろしくお願いいたします

ICPC2018国内予選に参加した

参加しました

参加しました

A,Cの2完でした。

イカれたメンバー紹介

  • ぼく(@xztaityozx_001)
    • いつもはC#で参加しているヤツ。AtCoderレートがそろそろ茶色に落ちる
    • 激しい憎悪によって目覚めた伝説のバトルメイド1
  • wheson(@wheson)
    • 実質水色の緑。笑顔が素敵。
    • vimのDockerfileを試して、dotfilesを更新したのに反映されない!って怒ってたけどpushしてなかっただけの悪いやつ
  • eliza0x(@eliza0x)
    • いつもはHaskellで参加してるヤツ。感情がすぐに無になる
    • 激しい憎悪によって目覚めた伝説のバトルメイド2

ICPC2018国内予選0問題「参加」

すっごいあめだったので、ぜんじつ、おうちに、かえれませんでした
ちかくにそぼのいえがあるので、ひなんしました。

あさおきたら、あめがやんでいませんでした。ぬれながらがっこうにいきました。
がっこうについたら、むわっとしていました。さいあくでした

そうこうしていたら、めんばーがしゅうごうしたので、ACしました

準備

正直服とか靴とかびしょびしょでコンディションは最悪。それでもなんとか参加できそうであったので、PCのセットアップ、ホワイトボードや飲み物の用意をしました。この日、僕は家に帰れないことが確定していたため、手持ちの服を温存するために、メイド服を着ました。これは去年の11月にゼミ内の圧力により手に入れた暗黒の力です。面倒なことにこれを着ている間は「メイド長」という別の人格が宿る設定なので、色々手間です。この記事ではこの設定が守られない箇所があります。よろしくおねがいいたします。

これについてもう少しあって、正直ぼくはメイドさんという属性は好きだし、手持ちのメイド服もフリフリしててかわいいんですが、できれば誰も見ていないところでひっそり自分だけで楽しみたいと思っています。

因みにもう一着あるのですが、それはeliza0xが着ていました。

なのでここから先は二人のメイドと男が競プロしてる情景を思い浮かべながら読んでください

開始〜A問題AC

開始と同時に前回の教訓を活かしてALLを3部印刷しました。ステープラーで3部をまとめましたが、途中でステープラーがぶっ壊れて泣きました。

Aを読んでいたwhesonとeliza0xが「やるだけ」と言っていたので、また自明に実装の早いwhesonが実装しました。

ACまで10分ぐらいだったのでいい感じだと思いました。

B,Cを読む

Bをeliza0xとwhesonで考察しました。日本語が難しかったので、読解に時間がかかりましたが「実装激重だけどやるだけ」という感じだったのでeliza0xが実装することに。この間 ぼくはあとの問題のためにテンプレを作り、Cを先に読んでいました。

Bの実装が始まったのでCについてwhesonに説明しました。すると「しゃくとりするだけでは?」みたいな提案を受けたので、「109^ だけど大丈夫か?」と聞きました。なんやかんや話してみましたが、まぁ大丈夫でしょwとなったので愚直なしゃくとりを書く方針になりました。

Bがバグる。Cを通す

Bが激重だったのでバグってしまいました。「バグったら印刷して交代」という作戦を取ることにしていたので、Cをやることに。実装がちゃんと降りてきていたみたいなのでwhesonに任せました。

この辺から暑くてメイド服は半脱ぎ状態でした。

しゃくとり自体はすぐかけたみたいなのでテストケースを回すと、計算が終わらないので最適化オプションをつけると、ビビるぐらい計算がはやくなってみんなでビビりました。サンプルはあっていたので提出しAC

無限

ここからBの実装に無限にやられてしまいました。こんがらがってしまった時点で別の誰かが実装を最初からするほうが良かったのかもしれません。

eliza0xからのヘルプに答えつつ、残りの問題で解けそうなのが無いかwhesonと探しましたがぼくは最大流の波動を感じませんでしたし、DPのwhesonもどうやっておとせるかわからないということでした。

G問題が構文解析だったので構文解析のeliza0xに問題概要を説明すると「めっちゃムズいやつやん」と悲鳴をあげていました。

このあとPCのグラフィックドライバがぶっ飛んだり、雨が強くなったり、暑すぎてメイド服をやめたりといろいろありましたが、結局Bを通すことができませんでした。

まとめ

模擬では良い結果を出せただけに、今回の2完は少し悔しいものとなりました。ぼくとwhesonは今年が最後のICPCでしたが、eliza0xはまだ参加できるので、来年の活躍を楽しみにしつつ消えることとします。

第36回シェル芸勉強会@限界キャンパスサテライトを開催した

この限界のはてに、まだ救いがあると思っている

お前が生まれたこの世界は、お前を救ってくれるとまだ信じている

なんかこんな感じのことをメタルギアで聞いた気がする。

震源+大雨=限界

弊キャンパスは直近の地震震源の真上ぐらいにあったところです。ここにこの間の大雨を合わせるとまさに限界!という感じです

大阪サテライトがこの雨の影響で中止となってしまったため、家に変えることも出来ないぼくはこの限界キャンパスで勝手にサテライトを開催することにしました。

あーたのしい

午前の部

鳥海さんによる文字コードの講義が始まりました。難読化クラスタとしては何かネタが転がっているかもしれないとワクワクしていました。

まずはlocaleiconvのような文字コードなどに関わってきそうなコマンドについてでした。
ずっと「ja_JP.utf8ってなんやねん冗長やなオイ」って思ってたんですが、どういう意味なのか解ることが出来てよかったです。

そのあと基数変換の話題ではbash$((2#bbbb))というパターンで変換できると知り驚きました。これすごい便利

いよいよ文字コードっぽいところに来た時、続きは次回ですとなっりました。えっ次回も参加するしか無い

昼休憩

昼休憩の間に限界サテライトからLTの配信が出来ないかどうか試していました。手伝ってくれた方々ありがとうございました。

限界サテライト側の機材不足で、音声がクリアに拾えないという問題があったため、結局配信は無しということになりました。悔しい・・・

昼飯を食ったあとは完全に体力の限界という感じでした。でも家に帰る手段も無いのでこのまま午後も見ることにしました。あとこれは秘密ですが、気づいたらメイド服を着ていました。

午後の部

とっても楽しい問題の始まりです。今回は時間内に解けた問題が全然ありませんでした。チクショー

因みに問題と解答はここです

問1

welcome.txtというファイルに仕込まれたバイナリを解析して、AAを見つける問題。いきなりヘビー過ぎて泣いた。とりあえずxxdしてみると不思議な模様があったので目を細めて見てみると0x00が紛れていたので、sedしてみました

するとめちゃめちゃなAAが出てきたので、適当にターミナルの横幅を動かしてみると70ぐらいだと解りました

cat welcome.txt | sed 's/\x00/@/g' | fold -70

因みに幅が70だったのは、toiletコマンドの出力の幅が70だったからだそうです。なるほどな〜〜〜〜

問2

フォーマットがめちゃくちゃなファイル名を揃える問題。こういうのはよくありそうだし、できると最高かもしれないですね

これはゴリゴリやればいいなとおもったので、ゴリゴリ。

ls -1|nkf -Z|sed 's/[0-9]/& /g;s/[aA-Z]/ & /g'|sed -r 's/^([0-9]).*([aA-Z])[^組]/\1年\U\2組/g'|sed 's/組組/組/g'|paste <(ls -1) - | xargs -n2 echo "mv" | bash

まずsedで年次と組を分離し、その後またsedしました。ちょっと冗長ですねこれ

因みに、ぼくは全角英数と半角英数が混ざっていると死にます。

問3

2018年の日付のうち2,3,5,7が4つ含まれる日付を列挙する問題。 例えば2018/07/23と言った感じ。
4つあるかどうかgreptrで削ったあとawklengthを見ればいいなと思っていたんですが、日付の列挙がうまく出来なかった・・・

時間内には解けなかったんですが、dateutils.dseqというコマンドがあるよということだったのでそれを使って解いてみました。

dateutils.dseq 2018-01-01 2018-12-31|sed -E 's/[^2357]//g'| paste - <(dateutils.dseq 2018-01-01 2018-12-31)|awk 'length($1)==4{print $2}'

pasteを使えるようになってから、よく使うようになりました。とっても便利ですよねこのコマンド

問4

tanzakuファイルをcatすると・・・

$ cat tanzaku
┏ ーー-┷-ーー┓
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┗ーーーーーー┛

このように表示されるのでこの中に俳句を入れる問題。ゴリゴリでいけそう

字余りするところは全角スペースで埋めてtetayoko。そのあとはsedの後方参照をつかってそれーという感じ。見た目ほど難しくなかった

問5

cowsayコマンドの出力を右向きにする。ただし文章はひっくり返しちゃダメ。
見た瞬間うっとなるのは響け!ユーフォニアム問題に似たものを感じる。

これは最初にrevしたあとsedで行を選択して末尾にスペースを埋め込んでいく戦法を考えました。でもあんまりよくないし何よりもめんどくさいので脳を休めてた。

問6

seq 20のうち素数である番号を○で囲む問題。

1
②
③
468
9
101214
15
161820

こういう感じですね。午前でやったことを活かして行こうと思い。まず②のxxdを見る。ASCIIコードを見つけて、それを基準に差分を足していけばいいのでは?と思ったのでゴリゴリしてみる

seq 20|factor|awk 'NF==2{print $2}'|xargs -I@ echo "echo \$((0xe291a1+@-2))"|bash|bc <(echo "obase=16") |tr '[A-F]' '[a-f]'|sed 's/$/0a/g'|xxd -p -r|paste <(seq 20|factor|awk 'NF==2{print $2}') -|awk '{print "s/^"$1"$/"$2"/g"}'|sed -f- <(seq 20)

前回のシェル芸勉強会で覚えた-f-も使えたので良かった。ちょっと冗長なので、他のシェル芸人さんみたいにスマートなやり方も鍛えていきたい

問7

textというファイルには見えない文字が含まれているらしい。どこにどんなのがあるか調査する問題。

調査するというのが難しかったので、とりあえずどんなのがありそうなのかbatで見る。すると・・・

丸見えになったのでコレで良いのではとなってしまった。この辺でもう脳が死んでたのでこんな解答しか出来なかった・・・

問8

最後はルビをふる問題。シェル芸人からの挑戦状を読んでいたので、sedで送り仮名を削りつつ、ルビのペアを作るのは出来てたけど上につける時のスペースの入れ方がわからなくてダメだった。

column -tでいいよということだったので覚えていきたい。

LTしたかったやつ

都合でいつものパワポテーマで作れなかったんですが。また難読化でLTする予定でした。今回は日夜手で難読化しているシェル芸人さんたちのために難読化コンバータを作りました。Go製です。ぜひ使ってみてください

因みにぼくは使ったことないです

まとめ

シェル芸勉強会はやはりサテライトでみんなで集まってやるのがたのしいですね。一人でサテライト開いても寂しいだけでした。問題が激しかったので寂しがっている暇はありませんでしたが。次回も参加したいなーとおもっています

今回もとても楽しかったです!ありがとうございました!!!

ICPC2018国内模擬に参加しました

参加した

参加しました

ABCEの4完でした。

イカれたメンバー紹介

  • ぼく(@xztaityozx_001)
    • いつもはC#で参加しているヤツ。ICPCには無いので実力が2割しか出せない
    • バグ産みマスター
  • wheson(@wheson)
    • 実質水色の緑。紅茶が好きらしい
    • vimのDockerfile試しておいてって頼んだのにスルーした悪いヤツ
  • eliza0x(@eliza0x)
    • いつもはHaskellで参加してるヤツ。C++に翻弄されるのが好き
    • 構文解析は任せろって言ってた

敬称略します

準備

僕の研究室を会場にすることになったので、PCのセットアップをした。僕以外の二人がUS配列を使う人たちだったので、Fcitxの設定を色々した。
エディターはvimで良いだろうとなったので、設定ファイルをかき集めてシンボリックリンクを貼り直すようなスクリプトでも作っておくか〜と思ったけど、Dockerでいいじゃんとなったのでそっちを用意した。

どのターミナルが誰のvimかわからんみたいになったので、ノード名を変えるとかしたほうが良さそう

直前にプリンターが死んだけど気合で直した。えらい

開始〜A問題ACまで

とりあえず全部印刷して、A,B,Cをざっくり見た。whesonが「Aはやるだけですね」と言ったので自明に実装が早いwhesonにまかせてB,Cをeliza0xと読むことにした。

Cを読んでいたらBNFが見えたので、eliza0xに投げた。ワクワクして「やるだけですね」と言ってた。
Bを読んでいたeliza0xが条件を式にしてくれていたので、ほぼ読んでないけど書けそうになった。

そうこうしているうちにwhesonがAを通した。ここまででだいたい15分だった。

D,Eの考察とCの実装

eliza0xが先にC行けそうなのでやりたいとすごいやる気だったので譲った。その間Dをwhesonと眺めることにした。

各桁にはコレだけ目的の数があるよね〜〜って式を立ててたんですが、ホワイトボードで列挙して数え上げたときと誤差がでて死亡。任意の2つの数字の組み合わせで、小さい順に並べると二進数っぽい増え方するよね〜って言ったりしていたけど、ダメそうだったのでEを先に見ることに。このときeliza0xは半分ぐらいCが出来ていたっぽい

これは失敗だが、3部問題を印刷しなかったので、全員が一度に問題を見れなかった。なので先にwhesonにEを読んでもらった。

whesonが「グラフですね」というのでイヤだなーと思っていたが、条件を聞くと二部グラフの波動を感じたので言った。whesonも少し考えた後、目を大きく見開いてそうですねといっていたので、ほぼ考察終了。このときの彼の顔がまさにピンときたみたいな顔だったので忘れられない。

「ホンマに二部グラフなんか」と思ったので条件を再度精査して、ホワイトボードに書き起こす。そしたら二部グラフ丸出しだったので、そうっぽいということになった。

ライブラリの所有者で実装が完全に頭で出来ていたwhesonがEを書くと言っていたので、僕はBを脳内コーディングして、Cを待つことに。

B,C,Eをバグらせる

この辺は目まぐるしく入れ替わったので、よく覚えていない。

たしか、パーサーはうまく動いているけどどこかが変らしく、eliza0xがCをつまらせていたので一旦、実装の軽いBをやることに。脳内コーディングとeliza0xとのペアプロでそれなりの速度でコードがかけたがやはりどこかがおかしく、プリントアウトしてwhesonと交代した。

ライブラリの写経をしている間に、eliza0xとCの問題文をもう一度よく読み、ほしい答えを読み取る。すると、実装が降ってきたみたいなので交代。この時whesonもどこかをバグらせていたみたいなのでプリントアウトして交代。ここでだいたい2時間経過ぐらい。

怒涛のAC

完全に降りてきていたみたいなのでさっとCをeliza0xが通す。Bも関数の1つがintを返さないと行けないのにboolを返してたという大ポカを修正してちょこっといじれば通ったので、whesonに交代。

Eのバグは写経ミスらしかったので、コーナーケースとかの処理をして、サンプルが通ったのがだいたい終了5分前ぐらい。この間ずっと田中ヒメの過呼吸みたいなやつの真似をしていたんだけど、whesonは気づいてくれなかったし、eliza0xは落ち着いてと言っていたので、やるタイミングを完全に間違えた。

Eを無事ACし、やったぜー!となっていた時は終了2分前だった。

終了後

終了後、弊学から参加していた人々が集まった。みんな口々に感想を言ったり、ここでバグらせたなどを言ったりしていた。あとでランキング?みたいなのを見るとselectedになっていたので素直に嬉しかった。

次は予選本番ですね!!!!!!!!同じ調子でできれば予選突破も夢じゃなさそうなので頑張っていきたい。

今回はコーディング環境周りや、手順、役割配分などで課題も見え、単に座るだけをせずに済んだのでとても良い模擬だった。ちなみに同日のARCは参加TLEしたので、問題すら見ていない・・・・・・(参加したかった)