2006-03-20

水玉潰しゲームソルバーに挑戦

水玉潰しを解くスクリプトを書こうと思い立ちました。が、やたらと時間がかかります。かたっぱしから手を生成して、それをシミュレートするという力技なので、時間がかかるのは当然です。ラスト何か数手であっても数分かかったりします。何かヒューリスティックを考えないといけませんね。




def main():
pattern = [[0,4,4,0,0,0],
[0,0,0,0,0,0],
[2,0,0,0,0,0],
[3,0,0,0,0,0],
[3,0,0,0,0,0],
[0,0,0,0,0,0]]
solution, tank = solve(pattern, 13,13)
print solution, tank

def play(game, sequence=[]):

for x,y in sequence:

game.dropByUser(x,y)



def solve(pattern, tank=10, limit=2):

tankMax = -1

solution = None

game = Game()

for currentLimit in xrange(1, limit+1):

print currentLimit

# for each sequence:

for seq in sequences(currentLimit):

# heuristics

if unsolvable(pattern, seq):

continue

# play game

game.init(pattern, tank)

play(game, seq)

# if solved and tank is larger than prev best,

# store tank and solution

if game.isSolved() and game.tank > tankMax:

solution = seq

tankMax = game.tank

if solution:

return solution, tankMax

return solution, tankMax



def sequences(limit):

if limit==0:

yield []

return

for x in xrange(6):

for y in xrange(6):

for tmp in sequences(limit-1):

yield [(x,y)] + tmp

return



_tmp_pattern = [[0 for x in range(6)] for y in range(6)]

def unsolvable(pattern, seq):

for y in xrange(6):

for x in xrange(6):

_tmp_pattern[y][x] = pattern[y][x]

for x,y in seq:

_tmp_pattern[y][x] += 1

if max([max(z) for z in _tmp_pattern]) < 5:

return True

else:

return False





class Game:

def __init__(self):

self.tank = 0

self.cells = {}

for y in xrange(6):

for x in xrange(6):

self.cells[x,y] = Cell(self)

self.splashes = []

self.chain = 0



def init(self, pattern, tank=10):

for y in xrange(6):

for x in xrange(6):

self.cells[x,y].drop = pattern[y][x]

self.tank = tank



def dropByUser(self, x, y):

self.chain = 0

return self.drop(x, y)



def drop(self, x, y):

self.tank -= 1

self.cells[x,y].growDrop()

while len(self.splashes) > 0:

s = self.splashes.pop(0)

s.move()

if s.alive:

self.splashes.append(s)



def notifyCrash(self, cell):

self.chain += 1

if self.chain == 3:

self.tank += 1

self.chain = 0

for (x,y),value in self.cells.items():

if value==cell:

break

for dx,dy in [(1,0), (-1,0), (0,1), (0,-1)]:

self.splashes.append(Splash(self, x,y,dx,dy))



def isSolved(self):

for c in self.cells.values():

if c.drop!=0:

return False

return True



def __str__(self):

string = "tank: %d\n" % self.tank

for y in xrange(6):

for x in xrange(6):

string += "%d " % self.cells[x,y].drop

string += "\n"

return string



class Cell:

def __init__(self, game):

self.game = game

self.drop = 0



def growDrop(self):

self.drop += 1

if self.drop==5:

self.drop = 0

self.game.notifyCrash(self)



class Splash:

def __init__(self, game, x, y, dx, dy):

self.x = x

self.y = y

self.dx = dx

self.dy = dy

self.game = game

self.alive = True



def move(self):

self.x += self.dx

self.y += self.dy

if (self.x<0 or 5
self.alive = False

elif self.game.cells[self.x, self.y].drop > 0:

self.game.cells[self.x, self.y].growDrop()

self.alive = False





if __name__ == "__main__":

main()



2006-03-19

Daniel L. Schacter / なぜ、「あれ」が思いだせなくなるのか



最近、物忘れがひどすぎるので、この本を買いました。



固有名詞には特別な意味はない。その名前で呼ばれる個人を象徴するが、その個人の性質を暗示することはない。[...] 名前がジョン・ベーカーだというとき、比較的よくあるアングロサクソン系の名前であるということの他には、彼個人についてほとんど、あるいはまったく何も伝えていないのだ。 (p.79)

よっぽどのことがない限り、私は、本名を知っている人を、あだ名やニックネームで呼びません。たとえば「ふるっち」や「ふるちん」などの呼び名があるからといって、誰かが私を識別することの役に立たないからです。ただし私の鼻が、他人の鼻より際立って赤い場合に「赤鼻の古川」とか「トオル・ザ・レッド」という呼称には意味があると思います。身体的特徴を口に出すことの倫理性は別として、認識のしやすさという点で、便利です。



記憶結合の失敗が原因で、実際に経験した出来事と、ただ考えたり想像しただけの出来事とが混乱することもある。たとえば、これから外出しようというときに、家のドアを閉めて鍵をかけなければと考える。その一時間後、車のなかで、あなたは突然パニックに襲われる。自分は本当にドアに鍵をかけてきたのか、それともただ想像しただけなのか?(p.117)

ちなみに私は、通勤途中に「ズボンをはいたかどうか」不安になることがあります。毎日、似たデザインのスーツを着ているので、ズボンをはいた記憶があいまいのなのです。あと、トイレでズボンを下ろしたときに、ファスナーを数秒前にあけたのか、元々あいていたのか分からなくなります。せっぱつまっているときは、特に。



つきまとう記憶を本当に和らげるためには、それらを認識し、直面し、対処しなければならないのだ (p.231)

トラウマというほどではないにしても、思い出すと逃げ出したくなる記憶が多々あります。どこかで向き合わねば。



矢幡洋 / とにかく目立ちたがる人たち



事態を客観的に分析したいと考えている人にとっては、ヒストリニオクスのトークは分析的な情報に乏しく、自分の主観的な体験を強調しているだけに聞こえる。 (p.101)


「これは大問題です」とか言うので話を聞いてみると、全体から見るとごく小さな障害に対して過剰に反応しているだけ、ということがあります。私は、「大」「非常に」「超」などの接頭辞を使わないと、他人の注意を集められない事象は、およそ重要ではない、という仮説を持っています。



ナルシストは、自分が他人に与えたものに関しては過大評価し、自分が他人から受け取ったものに関しては過小評価する傾向が強い。 (p.133)


しょうもない情報の提供や、たいした手伝いしかしてもらっていないのに、恩着せがましく「今期の成果」として公表されるときの、がっかり感はすさまじいものです。



以上、自戒もこめて。



日経ビジネスアソシエ 2006.04.04

日経ビジネスアソシエ 2006.04.04 号の特集は「1週間行動計画」です。その特集とは関係ありませんが、笑福亭鶴瓶のインタビューがありました。「らくごのご」や「鶴の間」など即興の笑いをつくる挑戦をしていますねと言われたことに対して、以下の発言です。



これこそプロの技やと思うて見せつけてるんです (p.110)


かっこいい。プロジェクタにつないだ PC 上で即興プログラミング、セミナー中にホワイトボードで数式を展開して解を出すなどの後で、何か発言や提案があると、うなづく率があがる気がする。



2006-03-14

JavaScript/Migemo 0.6 好きなパスに辞書を置けるように変更など

今日は非常に不機嫌で、非生産的な1日だった。どう考えても仕事なんぞ手につかないと思ったので、6時ごろに退社する。気晴らしに JavaScript/Migemo に手を加えることにする。バージョン 0.6 の変更点は以下の通り。




  • いいかげんな単体テストを追加。デバッグや、リファクタリングの前には単体テストを作ってから、修正することにした。

  • 「n」で終わるときの、かな候補を修正。これまでは「n」で終わるときも、促音が入っていた。「kan」の候補に「かっ」が入っていた。この促音候補を出さないようにした。

  • 辞書のパスを自由に指定できるように変更。これまでは HTML と同じディレクトリに、辞書が保存されている必要があった。あまりにださい上に、辞書ファイルの個数が多いので、任意の(ブラウザがアクセス可能な)ディレクトリに辞書をおけるようにした。クエリする前に migemo.initialize("./foo") を呼び出すと、./foo 以下に辞書ファイルを探しにいく。



2006-03-13

JavaScript/Migemo が名前空間を汚さないように修正した

職場の検索ツールに JavaScript/Migemo を組み込もうとしたらメソッドがないとかいうエラーがでた。デモではちゃんと動くのに。コードを見たらメインのプログラムと migemo.js との両方で initialize() 関数を定義してることに気づく。JavaScript/Migemo が名前空間を汚しまくっていたのだ。というわけで、公開関数は migemo、非公開関数は _migmeo オブジェクトの中で定義しなおしたら、めでたく動作するようになった。



2006-03-11

JavaScript/Migemo ページのスタイル変更

拙作の JavaScript/Migemo が、いつも読んでいる Moongift オレンジニュースで紹介されていて、非常にうきうきである。アクセスが増えたときに、ページのデザインがしょぼいと恥ずかしいのではと思い、スタイルを変更した。自意識過剰っぷりを発揮した割には、およそたいしたデザインではない。ル・クルーゼのイメージ。



Le Creuset ココット・ロンド 20cm オレンジ


2006-03-09

藤田憲一 / 金持ち兄さんの王道 専門家をカモにする人・される人

金持ち兄さんの王道―専門家をカモにする人・される人
藤田 憲一
講談社 (2003/04)
売り上げランキング: 49,587


投資の本のはずだったんだけど、マーケティングの勉強になる。著者がマーケターだからか。



あなたが彼ら [専門家] に任せていいのは、「情報の提供」と「労働」だけである。「考えること」「判断すること」は、絶対に人に任せてはいけない。 (p.61)

相手がしょぼければ、そのとおりだろう。けれど、こっちがしょぼいと、相手の判断が正しい可能性が高い。そして、カモにされる、と。



あなたはそこの「麦トロ牛タン定食」が目当てで通っている。しかし、麦トロ牛タン定食はすぐに売り切れる。仕方がないので、そんなときは「日替わり定食」を注文する。その店の経営会社は、あるときPOSデータを分析することにした。どうやら、人気商品は「日替わり定食」らしい。そこで、その会社は「日替わり定食」の供給を増やすことにした。

おお、これはやばい。



2006-03-06

椎木一夫 / エンジニアが30歳までに身につけておくべきこと

エンジニアが30歳までに身につけておくこと
椎木 一夫
日本実業出版社 (2005/10/20)


20代の間に身につけておけばよかったなぁ、と30代の私が思っているようなことが書かれている。Better Late Than Never ではあるけれど、若い新入社員の人に読んでもらいたいような本である。こんな本を読まなくてもいいような人を、採用すればいいのだけれど、私のように30過ぎて気づくような人間をうっかり雇う職場も存在するのだ。



新しい仕事に取り組む場合、いろいろ慎重に考えすぎると、着手できなくなったりする。そこで「とりあえず始めてみる」のだが、その仕事の目標・目的だけは明瞭にしておく必要がある。 (p.117)



仕事がうまく進まなくなると、人間誰しも「ダメな理由」を考えて上司に説明したくなる。[...] ダメな理由を考えている暇があるなら、「うまくいかせるにはどうすればいいか」と、ここでも前向きの提案が必要だ。 (p.165)

すごい会議っぽい。



2006-03-05

Series60で、ひとり Wiki のスクリプト

Series60 で、ひとり Wiki するスクリプトが、ダウンロードできなかったみたいなので、リンクを修正した。テキストファイル。



s60wiki-20060304.py.txt



xyzzy にも同じようなモードを作って、使っている。手作業で同期するのはだるいので、同期ツールも作った。が、職場の PC ではエラーが出たりと、いまいちなので、今週末に修正の予定。



2006-03-04

ハワード・ゴールドマン / すごい考え方

すごい考え方
すごい考え方
posted with amazlet on 06.03.04
ハワード・ゴールドマン 松林 博文
中経出版 (2005/12/01)


問題解決の際の、考え方を紹介している。人間の思考を、コンピュータの OS に喩えるという比喩は、私にとっては分かりにくい。



「正しい」(right)かどうかよりも、「効果的」(effective) かどうかがより重要となる。(p.90)

本来の目的に集中して、過程の正しさよりも、成果に集中したい。過程をおろそかするのではなくて、成果のための過程であるという考え方。あたり前なのですが、難しい。つい目先の最適化や正しさに走ってしまいがち。自戒もこめて。



誰もが根本的な問題だと思っているが簡単には口に出せない「タブー化した問題」のことを私は「ひどい現実」と読んでいる。多くの組織において「ひどい現実」が手つかずになったまま、問題を解決しようとしている。そのために表面的な問題解決にとどまってしまっていることが多い。 (p.93)

たとえば、あくまでたとえばですが「そもそも社長がしょぼい」とか、そういう平社員では手の出しようがなさそうな問題があるとすると、どうしよう、とか考えてみる。「社長を変えるなんて、無理だよなあ」ではなく、ではどうするか、という視点に立とアイデアが出るのかも知れない。優秀な参謀で固める、とか。しょぼいな。



忙しいことと生産的であることとは別物だということをはっきり理解する必要がある。 (p.124)

これこそ自戒しなければいけない。時間や労力をかけて取り組んだ活動を、無駄な行為であると認めるのはつらいけれど、認めないと成果に集中できない。