Comment detail

ライフゲーム (Nested Flatten)

Squeak Smalltalk で、二次元配列オブジェクト(a Matrix)を使って書いてみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| 行数 世代 現状 次面 八方 |

行数 := 10. 世代 := 50.
現状 := Matrix new: 行数 tabulate: [:行# :列# | #(1 0 0) atRandom].
次面 := Matrix new: 行数.
八方 := OrderedCollection new.
(-1 to: 1) asDigitsToPower: 2 do: [:組 | 八方 add: 組 first @ 組 second].
八方 remove: 0@0.

World findATranscript: nil.
世代 timesRepeat: [
    Transcript cr; show: (String streamContents: [:ss |
        (1 to: 行数) do: [:行# |
            (現状 atRow: 行#) do: [:idx | ss nextPut: ('□■' at: idx + 1)].
            ss cr]]).

    次面 atAllPut: 0.
    現状 indicesDo: [:行# :列# |
        | 総数 |
        総数 := 八方 inject: 0 into: [:和 :Δ |
            | 位置 |
            位置 := 行#@列# + Δ - 1 \\ 行数 + 1.
            和 + (現状 at: 位置 x at: 位置 y)].
        次面 at: 行# at: 列# put: (総数 caseOf: {
            [2] -> [現状 at: 行# at: 列#].
            [3] -> [1]} otherwise: [0])].

    現状 := 次面 flag: (次面 := 現状)]

Squeak Smalltalk の(Erlang にこそ及ばないものの…)比較的軽量なスレッドを利用して、全セルにおける生死の判断をマルチスレッドで処理してみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| 行数 マス目 ワーカ再開用 メイン中断用 スレッド群 |
行数 := 10.
マス目 := Matrix new: 行数 tabulate: [:行# :列# | #value -> #(0 0 1) atRandom].
ワーカ再開用 := OrderedCollection new.
メイン中断用 := OrderedCollection new.
スレッド群 := OrderedCollection new.
マス目 withIndicesDo: [:セル :行# :列# |
    | 再開指示 完了伝達 隣接セル群  |
    再開指示 := ワーカ再開用 add: Semaphore new.
    完了伝達 := メイン中断用 add: Semaphore new.
    隣接セル群 := {0@1. 1@1. 1@0. 1@-1. 0@-1. -1@-1. -1@0. -1@1} collect: [:Δ |
        | 位置 |
        位置 := 行#@列# + Δ - 1 \\ 行数 + 1.
        マス目 at: 位置 x at: 位置 y].
    スレッド群 add: [[
        | 計 |
        再開指示 wait.
        計 := 隣接セル群 count: [:隣接セル | 隣接セル value > 0].
        計 = 2 ifTrue: [計 := 計 + セル value].
        完了伝達 signal.
        再開指示 wait.
        セル value: (計 = 3 ifTrue: [1] ifFalse: [0]).
        完了伝達 signal] repeat
    ] fixTemps fork].

World findATranscript: nil.
[50 timesRepeat: [
    Transcript cr; show: (String streamContents: [:ss |
        (1 to: 行数) do: [:行# | (マス目 atRow: 行#) do: [:セル |
            ss nextPut: ('■□' atWrap: セル value)].
            ss cr]]).

    ワーカ再開用 do: [:再開指示 | 再開指示 signal].
    メイン中断用 do: [:完了伝達 | 完了伝達 wait].
    ワーカ再開用 do: [:再開指示 | 再開指示 signal].
    メイン中断用 do: [:完了伝達 | 完了伝達 wait]].
] ensure: [スレッド群 do: [:スレッド | スレッド terminate]]

Index

Feed

Other

Link

Pathtraq

loading...