Splatoon中に電子レンジを赤く照らして牽制する

f:id:piroz95:20160303211650j:plain
(台所の照明を消した状態です)

経緯

「Splatoonの試合中に電子レンジを使われると接続が切れる」という現象は、実家Splatoonプレイヤーの多くが悩まされていると思います。
僕の場合、無線LAN親機とWiiUが階をまたいで離れているので有線接続も難しいです。

家族は僕のSplatoonプレイに協力的で、レンジを使う前にSplatoon中か確認を取ってくれます。
しかし、キッチンとWiiUは遠いので何かと負担をかけてしまいます。
そこでHueを使ってSplatoonプレイ中かどうかをキッチンに通知することにしました。

最終的な構成

f:id:piroz95:20160303182303p:plain

WiiUの映像をキャプチャしてIkaLogが試合開始と終了を判別し、スクリプトを実行します。
スクリプトが自作アプリHotaruIkaのボタンを自動クリックすることで、HotaruIkaがHueのAPIを叩いてHueが点きます。

Hue

Philips hue(ヒュー) スターターセット 929000259907 リテールパッケージ

Hueはスマート電球と言えるものの一つで、遠隔操作で色や明るさを変えることができます。
色は普通の電球のような色から、カラフルな色も出せます。(ただ水色は出ない)
明るさは、最小にすれば直接見ても眩しくないくらいです。最大は眩しいです。普通に電球です。
他にもタイマー機能などがありますがまだ使ってません。

パソコンからHueを操作できるようにする

HueはAPIが公開されています。
HTTPリクエストでJSONを送るとJSONが帰ってくる形式のようで、とても簡単そうです。

折角なのでアプリは自作することにしました。
買って色々調べるまではJSONを投げる気マンマンでした。
が、そもそも公式でSDKとサンプルプログラムが用意されていて、JSONをパースするまでもない様子。

結局サンプルを基に改造したら実装する部分がほとんどありませんでした。

HotaruIka

f:id:piroz95:20160303180201p:plain
できたアプリがこれです。イカ関連で光りそうな安直な名前にしました。
特定のHueをオフ、黄色に点灯、赤に点灯のいずれかにします。
赤が試合中、黄色がSplatoonプレイ中を表します。
Splatoonのプレイを開始するときに起動すれば、自動で黄色の点灯を始めます。
適当なボタンを押すことで状態が切り替わるほか、一定時間放置や終了でオフになります。

IkaLog

f:id:piroz95:20160303210553p:plain

IkaLog って何ができるの

任天堂WiiU 用ソフト「スプラトゥーン」の画面をリアルタイム解析して、 いろいろなことができるソフトです。

https://github.com/hasegaw/IkaLog/blob/master/doc/IkaUI.md

IkaLogの機能は本当に色々あります。
例えば、自動録画とリネームを行うことや、
f:id:piroz95:20160303195238p:plain
stat.inkと連携して戦績を保存することができます。
stat.ink | ぴろずさんのイカログ

IkaLogの自動録画機能でHotaruIkaを操作させる

IkaLogのGUI版のIkaUIを用いました。
自動録画は、試合の開始時と終了時にスクリプトを呼び出すので、スクリプトを編集して、HotaruIkaのボタンを操作するように追加します。
IkaUIに付属するスクリプトは、AutoITを使って書かれています。
AutoITには、ウィンドウを探す関数やボタンを押す関数が用意されているので、自動操作が簡単に書けます。
SwingのボタンはAutoITで探せないようなので、WinGetPos,WinActivate,MouseClickといった関数でごまかしました。
マウスを操作するので、試合の合間にtwitterを見てたりすると誤操作があり得ます・・・

まとめ

  • 協力があって成り立ってます
  • 繋げる部分のわずかな実装だけでできた
  • Hueすごいし簡単に動かせる
  • IkaLogすごい
  • Splatoon楽しい

Hue高かったので、他の使い方を考え中です。IFTTTを試してみようと思います。

Splatoonの話はよく@piroz_jkでつぶやいています。
メインブキはダイナモローラーテスラです。

DDPC2016参加記

予選

Tasks - DISCO presents ディスカバリーチャンネル プログラミングコンテスト2016 予選 | AtCoder

A問題

やるだけ。

B問題

 (A_i,i)でソートして二分探索しながらシミュレーションっぽいのをやる
バグらせまくってつらくなったので、愚直解とソートして愚直の2つで30点取ってC問題へ

C問題

考察を頑張ると、削除をしまくるか、ある程度置換をした後先頭への挿入or置換をする2パターンになって、
後者のパターンはSuffix Arrayが必要だと分かる。Suffix Arrayのライブラリを持っていないので愚直SAを書くもそもそもSA以外の部分がバグっていたらしい。
点数を取れず時間切れ。

97位だけど17卒に当たるので本戦参加権を得た。

本戦前

DDPC参加者の朝は早い。7時起き。

準備・移動フェーズは特に問題無かった。
しかし、会場は電源が不足しているらしく予め充電しておいた方がいいとの情報が入る。手遅れ。

会場は、基本的に机に電源が無かった。電源がどうしても必要になったら特定の席に移る必要があった。
席は一つの長机を2人で共有する形。広くもないが狭くて困るほどでもなかった。

本戦

開始の合図が開始時間に遅れて始まる。開幕コンテストページに繋がらなかったが数分で回復。

問題一覧
Tasks - DISCO presents ディスカバリーチャンネル プログラミングコンテスト2016 本選 | AtCoder

A問題

やるだけ。

B問題

最小の時刻 tを求める問題なのでまず二分探索して、ある時刻 Tまでに総和を X以上にできるかの判定問題にする。
制約的に二分探索後の判定は貪欲っぽいと予想→貪欲でできた

ある時間に選べる料理はその前の時間でも選べるので、最後に選ぶ料理から順に考えると都合が良く、選べる料理で最もおいしさが高いものを選べば良い。
料理を時間の降順でソートしておき、時間を戻しながら適宜料理を優先度つきキューに入れ、美味しさが最大となる要素を取り出していくように実装。
AC。

C問題

B問題までがスムーズだったので順位が良かった。C問題は10点の部分点は自明で満点は難しそう、間の20点はDPっぽいので満点のヒントになりそうなので20点を狙う。
左から右へ見ていくDPは無理、区間DPもなんか違う。

括弧列A,Bに対して、(A)ABの条件を満たす塗り方の数がA,Bの条件を満たす塗り方の数から計算できれば解けそう。
結局構文解析をしながら配列をマージしていくDPのようなものが生えた。

最初の提出が10点(WA+TLE)だったので、MODを取るミスを疑ったが見つからない。
sum += sum + ans[i]なる謎の記述を訂正してまだ10点。
無駄な部分を計算しないようにしてTLEを無くす、WAが残り10点。満点のケースでもTLEが無くなったので一応満点も見えてきた。

辛くなってきたので一度D問題とE問題を見に行く。D問題は部分点がなくさっぱり分からない。E問題は部分点はあるもののデータ構造不可避な問題文を開いた瞬間バイバイ。
C問題のバグをなんとかする方針にした。

なんとか考察ミスを発見した。
括弧列を連結していくパターンで赤に塗った数と青に塗った数の差は一時的に K+2より大きくなるパターンがあることを見落としていた。
修正するがインデックスの変換をバグらせREを2回。
残り40秒で最後の提出。コンテスト終了の少し後にジャッジが走り切り、AC。やったぜ。

結果は15位でした。予選の順位や本戦に来ている人の強さからしてまずまず良い結果だと思います。
でもC問題はハマり過ぎた・・・

本戦後/感想

すぐに解説や表彰はなく、会社紹介や講演会、社内ツアーがあった。
社内ツアーは高い機械が動いている所が見れて面白かった。


DISCO本社の開催で説明やツアーが充実していたのでDISCOについては少し詳しくなったが、ディスカバリーチャンネルは会社のアピールをほとんどしていなかった。
撮影や取材をしていたので今後DDPCの様子が映る番組が放送されたりするかな・・・?

CODE RUNNER 2015 参加記

2位でした。とっても嬉しいです。おかげで懇親会では普段のN倍口数が増えて、参加記も文章が増えます。

開始前

紙ぺーぱーさん、とこはるさん、すぎむさんとお昼にカツを食べた。願掛けは意識してない。
会場の入り口前でchokudaiさんに遭遇した。
案内板らしいものはなかったのでchokudaiさんが居なかったら少し困ったかもしれない?

会場入り。受付してQUOカード10000円(ギリギリ首都圏外判定)とTシャツを手に入れる。
レッドブルを配っていたがおなかの調子があまり良くないのでスルー。
席について接続テスト。最初は繋がらなかったが数分で回復した。
始まるまで適当に机を整理してtweetdeckを眺める。

本戦中

考察と実装と感想をある程度分けてるので若干時系列が前後します。

開始直後、本戦問題を開くリンクを押してもリンク先が間違っていて何も起きない。URLを推測したら1発で当たった。

問題が長い。適当に読み飛ばしながら読む。
正の点数を得るにもそこそこステップが必要そう。仕事を受注して、仕事に社員を割り当てれば良いらしい。
仕事の納期に間に合わないと罰金があるので、仕事はこなせる分だけ受注しないと死にそう。
仕事の種類によって、得意な社員が異なるので、仕事に対して処理能力が高い社員を順に割り当てていき、期限ギリギリで終わるように人数を調整するという方針になった。

とりあえず色々な情報が手に入るgetinfoを叩いて情報をクラスにホイするプログラムを書いて、そこから点数を取れるようにしていく。実装がクソ重い。

第一世代プログラム

  • 仕事がなく、かつ待機している社員が15人以上いれば仕事を1つ取る。
  • 受注した仕事に対して、待機している社員から、その種類の仕事の能力が高い順に割り当てる。期限内に終わるようになるまで人数を増やす。

15人以上の待機を確保したのは、ある程度待機させた方が、来た仕事に対して高い適正のある社員が残っている可能性が高そうだから。

最初のプログラムを動かし始めた時点で既に一時間くらい経過していた。この時得られるポイントは最終的には8分の1になる。
大事な所だけを文章にすると短いけど実際問題を読んだり考察したりコード増やしたりを行ったり来たりしている。


最初のプログラムの効率が結構良かったらしく、前の順位表を見るといつの間にかランクインしていた。案外みんな大したことないのかとか、上位陣は潜伏して他のこと考えてるんじゃないかとか思った。

点数が得られるようになったので、仕事のデータなどをログに吐かせて考察する。
効率を上げるにはどんな指標が必要か考える。社員が50人と決まっていることを考えると、社員一人あたりの時間あたりの稼ぎ、つまり
(仕事の報酬) / (仕事にかかる時間) / (仕事に割り当てる人数)
が高いほど良さそう。
この値は仕事と、現在待機している社員のパラメータによって決まる。社員の割当方法は変更なし。今後この値を仕事の「指標」などと言うことにする。
指標は仕事が完了できない場合にはとりあえず-(罰金)としておいた。

ログを見るとこの指標は仕事によって大きく差があり、低いものは0.1未満、高いものだと0.7とかを超えた。
すると、仕事をせずに罰金を食らってでも、効率のいい仕事だけ取れば良いのではとなり、仕事を外注するというシステムがあるのでこれを利用したくなる。
仕事を取ってきて効率が悪そうなら外注にする。
また、効率のいい仕事を外注で見つけたらそれを割り当てる。

この方法で細かい試行錯誤をして次のようになった。

第二世代プログラム

  • 外注されている仕事を見て、指標の最大値が0.6以上だったら即座にその仕事に社員を割り当てる。
  • 外注している仕事が5つ以下かつ、待機している社員が15人以上いれば仕事を1つ取る。
  • 受注した仕事の指標が0.2未満ならば外注する。0.2以上ならば社員を割り当てる。

これを実行してみると外注の仕事ばかり取ってきた。外注は宝の山だった。
ほとんど考察していなかった経験値や社員の挿げ替えについてはもう手遅れという感じだったので、方針はこれ以上変えられないという感じになり、このプログラムで最後まで走ることになった。

順位がみるみる上がっていくのを観測できた、そのうち2位になって、さらに1位になった。やったぜ。
ここからはパラメータ調整職人になった。主に外注されている仕事を取ってくるしきい値が大事っぽい。
しきい値を上げると社員の割り当てがあまり起きなくなり、暇な社員が増える。15人以上になった時は受注で暇な社員を減らしていたが、やはり受注は指標があまり良くなかった。
時間あたりの金の効率 >= しきい値 * 仕事している人数
みたいなことが言えるので、働いている人数との兼ね合いを考えてしきい値を調整していた。


ものすごい勢いで追い抜かれて2位になった。パラメータ調整職人しても追いつけそうにない。
どこで差がついたのだろう。やはり挿げ替えや経験値を序盤に見なかったのが痛かったか。それとも割り当てのアルゴリズムが悪かったか。

終了30分前くらいから、市場に出回る仕事の指標が高くなる傾向があった。
外注に手を出す人が増えたのでいい仕事を見つける可能性が上がったのか、ヤケクソで好条件で外注してる人でも居るのだろうか。
外注の仕事をもらうしきい値0.6は最後には1.5になっていた。

コンテスト終了。100850点で2位。
1位,3位とはそれぞれ1万点以上差がついた。終盤は順位は変わらないなあと思っていた。

表彰

こういうコンテストで壇上に上がるのは初めてでとても嬉しかった。あと緊張した。
最初にポイントを稼いだコツを聞かれるの、感想が言いづらくて厳しい。
これ顔出し配信じゃんって思ったけど、そもそも上位に居た時点でかなり映っていたらしい。
10万円の使い道は検討します。

その他コンテストについて

人によって応答が帰ってくるまで異常に時間がかかることがあったらしい。幸運にも自分は全くそのようなことがなかった。
難しいだろうけど出来るだけ不公平がないように運営がんばってほしい・・・

問題は面白かったです。なんか利益を最大化するために部下の使い方など手段を問わないブラック会社が生えた。
ただ問題の要素はもう少し少ない方がとっつきやすい気がする。

前準備してた話

表彰の時にも話した前準備のことです。
ゲーム終了直後の記念SSがこれです。ザ・Swingという感じ。
f:id:piroz95:20151213014951p:plain

ぼくのかんがえたさいきょうのCODE RUNNER環境(クソ図でごめんなさい)
f:id:piroz95:20151213020842j:plain
を実現しようと準備してました。
去年の本戦でプログラムを複数作って、手動で止めたり走らせたりしたという話を聞いてそれ良さそうだなあと思ったので、じゃあwindowsのタスクマネージャー的な物を用意してプログラムを一部だけ止めて差し替えたりとか色々できそうだなあと思ったのですが、そういうことに向いていそうなスクリプト言語の知識がありませんでした😇
実現したこととしてはプログラムやサーバーが止まったときに備えてデータをセーブロードしやすいように支度したり、グラフにプロットできるようにしたり、ログを出力したり、クエリを効率よく投げられるようにしました。
結果として本戦で便利だったのはログ出力・グラフプロット・クエリライブラリの3つでした。
ログは標準出力垂れ流しと大差ない気はしますが、Eclipseのウィンドウから独立してるのは良いです。
グラフプロットは分析やパラメータ調整職人の時に役立ちました。
クエリは種類ごとに時間を管理したり、自動リトライとか、エラー処理を入れてかなり快適な感じにしました。
並行プログラミングやGUIが役に立ったのでプログラミング第三(講義)に感謝🙏

コンテスト後

懇親会。2位なので調子に乗れる。
大体お昼食べたメンバーやキーキさんと固まる。
uwiさんと周りの人が話してたが、僕は顔を知らなかったのでチームラボの人だとしか分からなかった。
去った後に周りに聞いてみたらuwiさんだった。話しに行かないと。(使命感)

懇親会の半分以上の時間はuwiさんと話してた。
Java競技プログラマーの超強い人と話すのは初めてだったので、ライブラリのことについて聞いて色々知見が得られた。
ボクシングを出来るだけ減らすと速いらしいです。データ構造全部自前不可避。
No.310 2文字しりとり - yukicoderの素晴らしさを力説されるなと、Javaに関係あったりなかったりする話題で盛り上がったと思う。

紙ぺーぱーさん、すぎむさん、キーキさんとCOCOSで夜ご飯。懇親会でサンドイッチ3切れしか食べていなかったので助かった。
COCOSは初だったが普通のファミレスだ。立地の関係か人は多かった。

作問の話になった。
ぐるぐるツアーはクソ。(ハマったから過剰にdisります)
www.hackerrank.com

CODE FESTIVALの時からデータ構造を布教されているので次は平衡二分探索木を書かないといけない気がする。


新幹線でおうちへ。参加記を書く宣言をしていたので書く。クッソ時間かかった。

関係ないけど

yukicoderで12/25まで毎日問題が追加されるAdvent Calender Contestが今アツイです。
順位表→順位表- yukicoder
Adventar
www.adventar.org

僕の問題が16日,水曜日に公開されるので是非解いてください。

yukicoder No.307 最近色塗る問題多くない? の計算量

唐突に解説を書きたくなったのでブログを生やしました。
嘘解法かと思って投げたのが想定解だった。

解説

writer解説
http://yukicoder.me/problems/769/editorial

想定解が計算量的になんとかなることの説明をします。

あるマスが{(H+W)}回色が変わると全てのマスが同じ色になります。(コドフェス2015リレーHっぽい)

よって、クエリで塗り替えられたマスの数の和が{HW(H+W)}になると、鳩ノ巣原理より、あるマスは{H+W}回以上色が変わるので、全てのマスが同じ色になっているはずです。

計算量は幅優先探索でマスの色を変える回数に比例するのと、クエリを読む分を合わせて{O(Q+HW(H+W))}になります。