読者です 読者をやめる 読者になる 読者になる

オフラインリアルタイムどう書くE08オンラインで参加しました

はじめに

2016/10/1開催の「オフラインリアルタイムどう書くE08」、残念ながら所用で行けなかったのですが、オンラインで参加し問題を解きましたので、その解説です。

問題

今回は松島さん作成の白黒陣取りゲームでした。

囲碁盤めいたマス目の格子点に、碁石めいた白黒の駒を置いたときに、白・黒の陣地の大きさを求める問題です。
陣地の大きさは囲碁とは違う考えで、「自分の駒4個で作られる、マス目に沿った長方形の内、その内側 ( 境界上も含む ) に相手の駒を含まない領域」の合計の面積とします。

詳細は上のリンクから問題ページをご覧ください。

解説

コードは次の通りです。

解くにあたって、このようなポイントがあるだろうな、と考えました。

  • 長方形のリストアップ
  • 相手の駒が長方形に含まれるかどうかの判定
  • 面積の計算

まず、長方形のリストアップに関しては、駒のx座標・y座標のリストだけ先に作っておいて、長方形としてありうる、x座標2個の組み合わせ×y座標2個の組み合わせを列挙、その中から4隅に駒があって、正しく長方形になっているもののみを選択、というようにしています。

続いて相手の駒が含まれるかどうかの判定です。これについては、E02 ぴったり含む長方形でのしえるさんの解法を参考にしました。
コード上では「標高」と表現していますが、「ある駒より左上にある駒の個数」を各座標 ( 端の隣のダミー座標含む ) に予め登録しておいて、対象の長方形の4隅に対して、その登録した個数を足し引きし、長方形内の駒の数を計算するというものです。
このように計算した駒の数が0個でなければ、「含まれる」と判断できます。

最後、面積の計算です。ただ、各長方形の重複具合を判定するのは大変だと思ったので、実際に盤面の中で陣地になったところを塗っていき、最後に塗られたマスを数えるようにしました。

ちょっと無駄があるような気もしますが、実装は非常に素直なんではないでしょうか。…ただ、しえるさんの手法を思い出すときにちょっと勘違いがあって、修正するのに結構時間を喰ったため、解けたのはロスタイム数分の時点になってしまいました。

終わりに

パッと見どうすれば良いのか分からないのですが、順序立てて整理していくと素直に解けるあたり、良い問題だったのではないでしょうか。次回は会場で参加したいと思います。