2011年9月13日

GDD2011JP DevQuiz 私の書いた回答コードその2

[ ソフトウェア開発 ]

GDD DevQuiz、今年の本命はスライドパズル。拡張された15パズルです。まずはJavaで解いて、最後にgo言語で上積みしました。

Java実装
Go実装

問題文は以下のとおり。

幅が 3 マスから 6 マスで、高さが 3 マスから 6 マスのボードが与えられます。 各マスは、パネルが置かれているか、壁があるか、空白であるかのいずれかです。 パネルには 1 から 9 あるいは A から Z のいずれかの文字が書かれており、同じ文字の書かれたパネルは存在しません。 壁は 0 個以上存在し、空白のマスはただ 1 つだけ存在します。 例えば、次のようなボードが与えられます。ここで、壁は = で、空白は 0 で表されています。

40=
215
=86

空白は、上下左右のマスのパネルと入れ替えることができます。上のマスのパネルと入れ替えることを U とよび、同様に、下左右のマスのパネルと入れ替えることをそれぞれ D, L, R とよぶものとします。壁を空白やパネルと入れ替えることはできません。
パズルを解くというのは、与えられたボードの各マスを操作して、ゴール状態に持っていくことです。
ゴール状態とは、上の行から各行順番に、左から右に 1, 2, 3, 4, ..., 9, A, ..., Z という順にパネルが並び、最も右下のマスに空白が配置された状態のことです。壁のあるマスに対応するパネルは存在しません。例えば、左上のマスが壁であれば、ボード上に 1 のパネルは存在しません。
(中略)
いま、使うことができる L, R, U, D それぞれの総数があたえられます。 この総数は全パズルで共有されています。 例えばあるパズルを解くために L を使い切ってしまった場合、 他のパズルでは L を使うことはできません。 この総数を超えないようにしながら、なるべくたくさんのパズルを解いてください。

このパズル、5000問あるのです。そして一問が0.01点。100問といてやっと1点。手で解くことをある程度防ぐ設問ですね。

15パズルでの評価関数は各駒のゴールに対するマンハッタン距離合計を使うのがポピュラーな模様。その方向で、A*探索をRubyで試しに実装してみてあまりの遅さに音をあげてすぐにJavaにうつりました。

まずはメモリをじゃぶじゃぶつかって試みてみました。この時点で一晩で1000問程度回答。かなり厳しいです。

次はゴール状態から初期状態に向かってのA*探索を同時に走らせる双方向A*探索してみました。これでもくろみ通り、探索空間が小さくなってかなり成績があがり、3300問程度。その後はパラメータを少し調整し、メモリを増やすなどして、4300問まで頑張りました。

メモリ使いすぎで探索中にMacBook使えないのが辛くて、こんどはメモリをあんまり使わない反復深化深さ優先探索(IDDFS)を実装してみました。が、新たな解はほとんどみつけてくれません。

このあたりで飽きたのでgoでIDDFSを実装しなおして遊んでいたら「探索したノード数が一定数を超えたらその時点で評価値最良のノードひとつだけ残してそこから再度探索する」という乱暴な枝狩りをおもいつきました。これがそれなりに効果的で、最終的には4818問で終了しました。

この問題、30人近くが5000問すべてを解いています。そのひとたちは、そもそもメモリの使い方を最初からすごくしぼっていて、私の無駄遣い富豪プログラミングとは一線を画している様です。評価関数もいろいろ工夫されています。コード公開しているひと多数なので、後でじっくりみてみようと思ってます。

GDD2011JP DevQuiz 私の書いた回答コードその1

[ ソフトウェア開発 ]

今年の11月に、Google Developer's Dayというイベントがあります。
一昨年までは先着順で瞬間的にチケットがなくなっていたらしいです(参加してないので知りませんが)

昨年から参加者には基本的に「開発者向けクイズを解く」ことが課せられるようになりました。その得点上位のひとから順に、入場の権利が与えられるのです。開発者向けイベントなのだから、合理的ですね。

昨年にひきつづき、今年も挑戦しました。各問題のために書いたコードをここにだしておきます。まずは、簡単なほうの問題5つのうち、私がといた3つから。

(この5つの問題は、2つだけ点数にカウントされるのです)

Web Game

シンプルな神経衰弱ゲームです。カードはクリックすることでめくることができます。全 64 セットを解くことで問題クリアとなります。

色が違うだけのカードが、最大1024枚出てくる神経衰弱。これを手でやろうなんていうプログラマはほとんどいないでしょう。

親切なことに、「ヒント」としてGoogle Chromeの機能拡張の例が出ています。これをベースに使えばとても簡単。JavaScriptでDOMさわってクリックして色チェックして覚えて、というだけOKです。

manifestを含むコードはここに置いています。
https://gist.github.com/1213056

Go!

Go 言語で、PNG 画像を入力として受け取り、その画像が何色使っているかを返す関数func CountColor(png io.Reader) intを実装してください。PNG 画像は io.Reader 型で与えられます。なお、入力の画像は R G B の各色の値が 0 から 255 までの 256 段階のいずれかであり、不透明(アルファチャンネルの値が常に 255)であることが保証されています。

これも、goのimage/pngライブラリを使えば実に簡単です。

一人ゲーム

数がいくつか与えられます。なるべく少ない手数で数を全て取り除いてください。あなたは 1 手で、
- 全ての数を半分にする(端数は切り捨て)
- 5 の倍数 (0 を含む) を全て取り除く
のどちらかの操作をすることができます。

簡単簡単、とおもったらちょっとだけひっかかりました。

「5で割りきれてかつ2で割りきれない数が残っている」ときに、その数を含めて5の倍数を取り除くのが良い場合と、良くない場合があるのです。

結局、こんなコード書きました。幅優先探索。

  1. キューから取り出した数セットの要素すべて5でわりきれれば終了
  2. 要素のなかに5で割り切れるが2で割りきれないものがあったら、5の倍数を取り除いたものをキューに入れる
  3. 全要素を2で割ったものをキューに入れる


2010年1月28日

The Art of Unit Testing

[ ソフトウェア開発 ]

最近読んだ"The Art of Unit Testing: With Examples in .net"という本がとっても良かった。Unit Testをはじめようとしているひと、運用で悩んでいる人は今すぐ読め! ってくらい良かった。

この本は、ユニットテストの基本的な考え方と基本的な書き方から始まります(Part 1)。

そして、ユニットテストで必須のテクニックである依存性の取り除きかたについて語られます(Part 2)。

その上で、ユニットテストをどう配置し走らせるか、どうやってリファクタするか、どんなふうに自動ビルドで運用するか、など実際に運用するときの考え方や方法論を解説します。そしてユニットテストのコードで陥りがちな罠(ひとつのテストにAssertion多すぎ、テストの名前が分からん、Setupに詰め込みすぎ、実行順序に依存、などなど)とその回避基準も明示します(Part 3)。

さらに、組織へのユニットテストを導入するにはどうするか(新しいことには抵抗がつきものです)を説明し、「タフ」な質問( 「これはどのくらい時間をとるの?」「これでほんとに効果がでるの?」など)にどう応えるか、回答例のカタログとともに説明します。最後の章では所謂"レガシーコード"に、どのようにユニットテストを適用していくのか、という話題に切り込みます(Part 4)。

上記で要約したとおり、「ユニットテスト」の話題に関する1から10までをカバーしてる本です。これだけ盛りだくさんで、厚さは300ページ程度と薄いのもよいです。でも内容は決して薄くないですよ。これからユニットテストを学ぶひとが最初から通読するのにはとても向いていますし、ある程度実践してるけど、いろいろうまくいっていない人(それは私)にも読み応えあります。

テスト駆動開発ベースの本や、JUnitの使い方の本はいままでもいろいろありましたが、ユニットテストの話題を網羅した、適切なサイズの本はこれまでなかったのではないかと思います。

"xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series)"や、"レガシーコード改善ガイド (Object Oriented SELECTION)"を読む前に読むのもよいのではないかと推測します(推測なのは、どっちも未だ読んでいないので...)

翻訳されていないのが惜しいです。もし誰も版権とっていないのならば、翻訳したいなー、と本気で思っています。アンオフィシャルに蠢き中ですが、既に翻訳はじまってるよ、などの情報ご存じの方いらっしゃったら教えてください。

そして、ひろってくださる出版社募集中。

2010年1月24日

アレグザンダー祭りで印象に残った一言など

[ イベント ソフトウェア開発 休むに似たり ]

先日、オブジェクト俱楽部のイベントアレグザンダー祭りに行ってきました。もりだくさんすぎて、未だに消化しきれていないのですが、一点強烈に印象に残ったのは、メインスピーカのJim Coplien氏による、おおむねつぎのような発言です。

俺たちは有用性が証明されたかどうかでなく、流行や気持ちよさ、直観、「のみ」で技術や方法論を追いかけている(ことが多い)

今週になってからtwitterでの議論の中で、こんな発言がありました:

if your only learning comes from asking other people what *they* think - how can you claim to personally know anything?
(このひとは、The Art of Unit Testing: With Examples in .net の著者です。良書なので近々紹介します)

これは開発関連のツールに関連した議論の中で出てきた発言です。意図は、先のJim Coplienの発言と同じだと、私は理解しました。

肝に銘じます。

2008年7月15日

iPhoneアプリが作りたい

[ ソフトウェア開発 ]

無事手に入ったことだし、iPhoneアプリが作りたい! と思っているのですが...
  1. 暇がない(言い訳、暇なんかつくればいくらでもある!)
  2. ネタがない(これは深刻かも。アイディアの種はちょっとだけあるので、育て中です)
  3. iPhone SDKにとっかかれない(これも言い訳
3.については、まあ言い訳ではあるものの、なんかきっかけがあればなあ、と思っていて、ここで提案されている勉強会が開催されるならぜひ参加したいなと思っています。