DDCC2019本戦に参加した感想
まとめ
- A, Bの2完
- アナウンスの人の声が良い
- ケーキが美味しい
はじめに
予選で272位 & 20卒だったので本戦に行きました。20卒枠は交通費も出るのでうれしいです。
起床
成功です。
DDCC始発部の朝は早い。
— ikd (@ia7ck) 2019年1月18日
到着
受付
受付は アルコール消毒→事前に送られていたQRコードを提示 という流れでした。ここで注意が必要なのは先にQRコードを用意しておかないと濡れた手でスマホを操作しないといけなくなりつらくなることです。受付の時点でアルゴリズム力(?)が試されていて、大変な場所に来てしまったことを思い知らされました。
名札とTシャツをもらってコンテスト会場に移動します。† F I N A L I S T † は強そうです。
#DDCC2019 pic.twitter.com/4G6pHSI8sw
— ikd (@ia7ck) 2019年1月19日
交通費精算
領収書を渡すとお金をもらえます。ありがとうございます。
そのうえ「コンテストがんばってください」と言われるので普段より良いパフォーマンスを出せる気がしてきます。
着席
席は自由だったので↓の左奥あたりに座りました。座席表があればTwitterの人とかに凸しやすかったですね。
前からパシャ pic.twitter.com/SOlNKh5V7A
— ddcc2019 (@ddcc_2019) 2019年1月19日
名札とTシャツの着用は必須らしい。暖房と日差しとで僕の席は暑かったです。
コンテスト(コード部門)
カウントダウンをするお姉さんの声が良すぎて聞き惚れていたらコンテストが始まっていました。ディスコ社の人なのかプロの人なのか気になります。
A問題
めちゃ緊張していて、日本語は読めるのに問題文が読めない状態になっていました。5分くらいかけて読むとだいたい分かって、制約のおかげで実装はラクになることまで分かったのでコードを書いて提出するとACしました。
Submission #4039227 - DISCO presents ディスカバリーチャンネル コードコンテスト2019 本戦
B問題
やっぱり問題文が読めないのでサンプルと交互に読むことでなるべく早く問題を把握することにしました。貪欲?が思いついて正当性はあんまり分かんないけどサンプルが合ったので提出するとACしました。
Submission #4039774 - DISCO presents ディスカバリーチャンネル コードコンテスト2019 本戦
PCの充電が少ない問題
前日に100%まで充電していたつもりがB問題を解いた時点で10%になっていました。ただ、残り5%からの粘りは目をみはるものがありました。人間サイドは座っているだけでした。
昼食
ビュッフェ形式で、ケーキとサラダを食べました。ケーキは各種3個ずつ食べました。チョコが美味しかったです。
もうすぐでビュッフェ❤️#ddcc2019 pic.twitter.com/H05FUhL1j4
— ddcc2019 (@ddcc_2019) 2019年1月19日
お腹を満たしたので、人々の名札のあたりを見ながら徘徊するだけの機械になりました。順位表の上のほうで見るIDが並んでいて壮観でした。
昼食の時間の後半は somq14 さんと楽しくお話することができました(ありがとうございます……)。
PCの充電が不安な人は今のうちに済ませておきましょうとアナウンスがありました。スタッフさんにコンセントの場所を訊いたら教えてくれたので優しかったです。
装置実装部門
とりあえず正の得点を出そうとしましたが最後までWAでした。出力形式が合ってなかったのかな。
ディスコ社紹介
ウェーハに線を引いてウエハースの表面にする工程を見ました。機械の操作画面が使いやすそうな感じで良かったです。
廊下の交差点では天井に360度カーブミラーみたいのが付いていて、出会い頭の衝突を避けられるようになっていました。
装置実装部門 決勝
装置動かしてますよー!#ddcc2019 pic.twitter.com/pks2LubuOi
— ddcc2019 (@ddcc_2019) 2019年1月19日
漏斗(ろうと)が水平方向(x軸・y軸)に動いて、赤と緑に光ってる箇所で水を受けとり排出口まで運びます。排出口にあるメスシリンダーに漏斗から水を注ぎます。時間内により多くの水をメスシリンダーにためられた人の勝ちです。
漏斗を高速に動かしすぎると水がこぼれてしまい、かといって遅すぎるとスコアは伸びないので難しそうです。
装置の様子は別モニターで見られたので、写真で見切れている右のほうで観戦していました。なにか動いているのを見るのはパソコンをカチカチしてるのを見るより楽しいと思いました。
表彰式
yosupo さんがコード部門と装置実装部門の2冠で30万円相当のPC+30万円+40万円を得ていました。すごい。
懇親会
ビュッフェ2回戦です。DDCCケーキが出ました。
今回はじめて本戦に行って気づけたのですが、料理が置かれるスペースが2箇所あるのでDDCCケーキも2つあります。
誰が最初に手をつけるんだろうと思っていたら、ほどよい頃合いでスタッフさんが切り分けて配ってくれました。すでにお腹いっぱいだったので僕は見送りました。
装置実装部門で使った装置のまわりにはスタッフさんが集まって議論?していたのでかっこよかったです。より正確な動作を実現するには、とかを話していたんだと思います(予想です)。
印刷された順位表が貼り出されました。すでに順位を把握していましたが念のため(念のため?)確認しました。3枚目の1番左上:101位です。
順位表🙌 #ddcc2019 pic.twitter.com/HO72yaRJKt
— ddcc2019 (@ddcc_2019) 2019年1月19日
最後に集合写真を撮って終わりました。けっこうはっきり写っていてびびります。ありがとうございました。
みなさんご参加いただき、ありがとうございました🙌
— ddcc2019 (@ddcc_2019) 2019年1月19日
集合写真🔽 #ddcc2019 pic.twitter.com/gAvCzyQSqS
テトリスのAIを作った
パソコンを使ったのでたぶんAIです。
AI
ver.1 ランダム
ピースをランダムに回転させてランダムな位置に落とします。すぐにゲームオーバーになります。
ver.2 評価関数
各ターンでピースの回転・落とす位置を全部試して一番よさげな手を選びます。
よさを決める要素はたとえば次のようなものが挙げられます:
- このターンで消した段の数
- いまの盤面で積み上がっているブロックの最大の高さ
これらに適当に係数をかけたものを評価関数として手のよさを評価します。
有効な手すべてについて評価して、一番良い手を選びます。
ver.3 GA
評価関数の各変数にかかる係数を少しずつ変えながら強いAIを探すのは精神に悪いです。
そこで次のようにします。
- 評価関数の係数が異なる個体 (AI) を複数用意する
- それらにゲームをプレイさせてみてスコアの高かった個体の一部を エリート とする
- エリート から1つ、全体から1つ個体をえらんでそれらから新しい個体をつくる
- たとえば係数が1種類だとして、係数$a$を持つ個体と係数$b (>a)$を持つ個体から新しい個体をつくるときその係数は$[a, b]$からランダムに選ぶようにします
- 一定数新しい個体ができたら古い個体たちは消して2に戻って繰り返す
- 適当な回数繰り返したら終わる
このような方法はGA (Genetic Algorithm) と呼ばれています。
思い出
もっと強いのを作りたかった。
GA...のつもりだけど、第5世代くらいで収束してしまっているのでダメです。
カーソル行の直前・直後に空行を挿入する micro の plugin を作った
micro editor で Insert Line Above/Below するプラグインを作りました。
VSCode で Ctrl+Enter
とか Ctrl+Shift+Enter
とかに割り当てられている *1 あれです。
レポジトリ
Demo
コード
実装のメイン部分は10行くらいなので、プラグインというには大げさでせいぜいマクロといったところでしょう。
function insertLineBelow() local v = CurView() v:EndOfLine(false) v:InsertNewline(false) end function insertLineAbove() local v = CurView() v.Cursor:Up() insertLineBelow() end
インストール
1 . ~/.config/micro/settings.json
の pluginchannels
の部分を次のように書き換えます。
{ "pluginchannels": [ "https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json", "https://raw.githubusercontent.com/ia7ck/insertline/master/channel.json" ] }
2 . micro の コマンドモードで plugin install insertline
を入力してEnterを押します。
使い方
コマンドモードで insertlinebelow
と打つと、カーソル行の下に空行が、 insertlineabove
と打つと、カーソル行の上に空行が挿入されます。
キーボードショートカット
デフォルトでは Alt+Enter
を insertlinebelow
に割り当てています。
insertlineabove
には何も割り当てていません *2 。
この設定は ~/.config/micro/keybindings.json
を編集することで変更できます *3 。
メモ
マクロじゃダメなの?
Ctrl+U
でマクロの登録、Ctrl+J
でマクロの実行ができます *4 が複数登録ができません。
プラグインの開発
ここ を見ると、~/.config/micro/init.lua
にコードを書けばプラグインが作れることが分かります。micro 本体が提供している関数や変数は ここ で確認できます。
たとえば、CurView()
は Go のコード内で定義されている View
構造体のポインタを返します。EndOfLine
は *View
型の変数をレシーバにとってカーソルを行の末尾に移動させる関数です。InsertNewline
も同様にして、現在のカーソル位置で改行する関数です。こういうのはIDEを使って複数ファイルを横断検索して、気になる関数とかがあれば定義元にジャンプする機能を使うといいです(と最近気づきました)。
Go だと *View
型の変数 v
に対して EndOfLine
を実行するにはドット .
を使って v.EndOfLine()
としますが、lua でそれに対応する記法は v:EndOfLine()
です。意図せず再帰的に関数が呼ばれるのを防ぐためには引数に false
を指定しておくといいみたいです *5 。
プラグインの公開
channel.json
と repo.json
を用意することで、micro のコマンドモードから plugin install
でインストールできるようになります *6 。ただし、上で示したように ~/.config/micro/settings.json
をあらかじめ編集しておく必要があります *7 。
*1:https://code.visualstudio.com/docs/getstarted/keybindings#_basic-editing
*2:なにか良いのがあったら教えてください
*3:https://github.com/ia7ck/insertline/blob/master/help/insertline.md#key-bindings
*4:https://github.com/zyedidia/micro/blob/master/runtime/help/keybindings.md#default-keybinding-configuration
*5:https://github.com/zyedidia/micro/blame/master/runtime/help/plugins.md#L171
*6:https://github.com/zyedidia/micro/blob/master/runtime/help/plugins.md#plugin-manager
*7:https://qiita.com/10sr/items/0ed6f3dc4a01159115fc#channel