Haskell Bowling を Squeak の Smalltalk で 2


The Log of the No22 - ボーリングのスコア計算 を拝見していて、短けーっとか思いつつ、ああ… size = 1 の条件分岐はいらねーな…と遅まきながら気づかされたりしたので少し整理するようにして書き直し。必然的に Sukuna 版の直訳気味に。

SqueakSmalltalk
SequenceableCollection >> score
   self isEmpty ifTrue: [^ 0].
   self size <= 3 ifTrue: [^ self sum].
   self first = 10 ifTrue: [^ (self first: 3) sum + self allButFirst score].
   (self first: 2) sum = 10 ifTrue: [^ (self first: 3) sum + (self allButFirst: 2) score].
   ^ (self first: 2) sum + (self allButFirst: 2) score
#(0 0 10 8 2 10 10 10 5 3 8 2 10 10 10 10) score   " => 201 "
Smalltalk 版を Ruby で直訳版
class Array
  def score
    return 0 if empty?
    return sum if size <= 3
    return first(3).sum + all_but_first.score if first == 10
    return first(3).sum + all_but_first(2).score if first(2).sum == 10
    first(2).sum + all_but_first(2).score
  end

  def sum
    inject(0) { |s,e| s+e }
  end

  def first(n=1)
    if n == 1
      self[0]
    else
      self[0, n]
    end
  end

  def second
    self[1]
  end

  def all_but_first(n=1)
    self[n, size - n + 1]
  end
end
[0,0,10,8,2,10,10,10,5,3,8,2,10,10,10,10].score   #=> 201