メトセラ2.0 [プログラミング - NSSetとライフゲーム]
ところで、結果はすばらしいものだった。
これを「メトセラ2.0」としよう。Macなひとはダウンロードして試してみて欲しい。
retainしないCFDictionary [プログラミング - NSSetとライフゲーム]
Perfect Hash [プログラミング - NSSetとライフゲーム]
ところで、コメントいただいたふたつのアイデアは、ぜひ実装してみたい。しかし僕がこんな頭いいアイデアを自分で思いつくということはないので、忘れた頃にコードを見て「なにやってんだ、これ?全然わからん」とかいいそう。ちゃんとメモを残しておかないと絶対言うに決まってる。もっとつまらないコードでも言ってるぐらいだし。
「メトセラ1.0」 [プログラミング - NSSetとライフゲーム]
NSSetとライフゲームの続き [プログラミング - NSSetとライフゲーム]
もうほとんど3年前のコードだけど、見ているといくつか気になることができてしまった。ちょっとだけと思いながらいじっていると、きりがなくなって書き直すことになってしまった。今日はこれで一日終わった。しかし、ひさしぶりに丸一日集中した。
NSSetとライフゲーム(その11、さらにおまけ) [プログラミング - NSSetとライフゲーム]
たまたまこれを見たよその人が、ソースはどないなっとんじゃい、と言うかもしれないので、アップロードしておく。
ソースとXcodeのプロジェクトファイルと、Xlifeなんかにあった初期データのファイル(動かないものがあったり重複があったりしてる)をzip圧縮したものを置いておく。
Xcodeのプロジェクトファイルは3.0用だけど、プロジェクトファイルだけを作り直してもたいしたことない。3.0でコンパイルするとNSStringの-cStringがdeprecatedだと言ってWarningが出る。次からはやめるわいな。
UIは最低限にしかなっていない。そもそもドキュメントのスタイルになっていない。まあ、NSSetの勉強用と割り切っていただきたい。
NSSetとライフゲームのメモは今度こそおしまい。
NSSetとライフゲーム(その10、おまけ) [プログラミング - NSSetとライフゲーム]
こないだのライフゲームをiMacの上でコンパイルしてみた。
そのままuniversal binaryに設定してコンパイルして動かすと、何も表示されない。
一カ所バイトオーダを決めうちしてるところがあって、このせいだった。カラーテーブル(NSColorの詰まったNSArray)から色を読み込んで、NSBitmapImageRep用のパックされた32ビットカラーに変換するところ。
エンディアンをチェックするようにした。どっちの石がどっちのエンディアンだったっけ?
NSSetとライフゲーム(その9、計算時間) [プログラミング - NSSetとライフゲーム]
NSSetとライフゲームに関するメモはこれでおしまいにしよう。
IntefaceBuilderで必要最小限のUIを作る。
データやカラーテーブルをロードし、世代交替の制御をして、表示する。表示にはNSImageView使うのが簡単。
それで
こんなのにして、ビルド。
まず、Sharkでどこが律速してるか確認。あれ?Sharkの集計方法って変わった?
自分のメソッドで言うと-[GoLAliveCell isEqual:]が5.5%、-[GoLAliveCell position]が3.8%でこのへんが一番重い。呼ばれる回数が多いからで、結局隣のセルを探す、その数を数えるというのが一番時間がかかってる。これは要素数をNとするとN^2のオーダーになる。
NSSetとライフゲーム(その8、evolve) [プログラミング - NSSetとライフゲーム]
ライフゲームの続き。
だんだん記述が丁寧になって単なるメモにしては重くなってきた。
今回は世代交替のプログラミング。NSSetの集合演算のおかげで簡単になる話。やっとNSSetを使うメリットの核心。
世代交替にはGoLSparceGameOfLifeのevolveメソッドで行うことにする。evolveメソッドは
- (BOOL)evolve { NSMutableSet *nextGenerationCells = [[self servivingCells] retain]; // (1) NSSet *vacants = [self findVacants]; // (2) [self appendNewBornTo:nextGenerationCells fromVacants:vacants]; // (3) if ([aliveCells isEqualToSet:nextGenerationCells] || ([aliveCells count] == 0)) { [nextGenerationCells release]; return NO; } [aliveCells release]; aliveCells = nextGenerationCells; generation ++; return YES; }
まず(1)で、次の世代に生き残るセルを選んでその集合を作る。
次に(2)で、vacantsと呼ぶ、現世代に死んでいるセルで次世代に生まれる可能性のあるセルの集合を作っておく。
(3)にvacantsの中から実際に生まれるものを選んで1行目で作った生き残りに加える。
その後で現世代をreleaseし、次世代を現世代にしてgenerationをひとつ進める。
それではその中身。