サンタクロース問題を Squeak Smalltalk で 3


id:sumim:20070608:p1 の続き。


rubyco(るびこ)の日記 - サンタクロース問題を解く(Ruby) で rubyco さんの書いた Ruby 版を、Squeak Smalltalk への意訳にチャレンジ。

…と申しましても、RubySmalltalk は互いによく似た部分があるため、例によってほぼそのまま変換して比較的簡単に書き換えられるわけですが(実際、必要な作業のほとんどはエディタでの検索・置換…(^_^;))、ただ今回、Ruby では Smalltalkセマフォ(a Semaphore)に当たる ConditionVariable が、排他処理ブロック内で使われることを前提とした仕様になっている点が意外でした。このことと、もとからスレッドセーフな a SharedQueue(Ruby の Queue)を使っている関係で、Squeak Smalltalk 版では排他処理は必要でなくなり、若干ですが、よりシンプルなコードになっています。

| reindeerNum elfNum discussNum santaSema rendeerQueue elfQueue reindeers elves n |

World findATranscript: nil.
Transcript clear.

reindeerNum := 9.
elfNum := 10.
discussNum := 3.

santaSema := Semaphore new.
rendeerQueue := SharedQueue new.
elfQueue := SharedQueue new.


reindeers := (1 to: reindeerNum) collect: [:k |
   [  | sema |
      sema := Semaphore new.
      [  (Delay forSeconds: 3 atRandom) wait.
         rendeerQueue nextPut: sema.
         santaSema signal.
         sema wait
      ] repeat
   ] fixTemps fork
].


elves := (1 to: elfNum) collect: [:k |
   [  | sema |
      sema := Semaphore new.
      [  (Delay forSeconds: 3 atRandom) wait.
         elfQueue nextPut: sema.
         santaSema signal.
         sema wait.
      ] repeat
   ] fixTemps fork
].


n := 3.
[n > 0] whileTrue: [ "santa"
   Transcript cr; show: 'Santa waits.'.

   [rendeerQueue size = reindeerNum or: [elfQueue size >= discussNum]] whileFalse: [
      santaSema wait.
   ].

   rendeerQueue size = reindeerNum ifTrue: [
      Transcript cr; show: ('Santa works with {1} reindeers.' format: {reindeerNum}).
      reindeerNum timesRepeat: [rendeerQueue next signal].
      n := n - 1
   ].

   elfQueue size >= discussNum ifTrue: [
      Transcript cr; show: ('Santa talks with {1} elves.' format: {discussNum}).
      discussNum timesRepeat: [elfQueue next signal]
   ]
].

reindeers do: [:rd | rd terminate].
elves do: [:ef | ef terminate]


出力例。

Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa works with 9 reindeers.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa works with 9 reindeers.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa talks with 3 elves.
Santa waits.
Santa works with 9 reindeers.


id:sumim:20070613:p1 に続く。