両替プログラム その2

出力が逆順なのが気持ち悪かったので、Prolog と同じになるように手直し。

Integer >> factors: factors amplitudes: amplitudes ifFail: failBlock
  "27 factors: #(24 11 3) amplitudes: #(0) ifFail: [^ nil]"
  | amps factor newAmps rest newFail |

  amps _ amplitudes.
  factor _ factors first.

  (factors size = 1 and: [amps last isZero]) ifTrue: [
    self \\ factor = 0 ifTrue: [
      Transcript cr; show: (amps allButLast copyWith: self // factor)].
    ^ failBlock value].

  newAmps _ amps copyWith: 0.
  newFail _ [^ self factors: factors allButFirst amplitudes: newAmps ifFail: failBlock].

  (rest _ self - factor) >= 0 ifTrue: [
    amps at: amps size put: (amps last + 1).
    ^ rest factors: factors amplitudes: amps ifFail: newFail].

  ^ newFail value
30 factors: #(10 5 1) amplitudes: #(0) ifFail: [^ nil]
"=> #(3 0 0)
    #(2 2 0)
    #(2 1 5)
    #(2 0 10)
    #(1 4 0)
    #(1 3 5)
    #(1 2 10)
    #(1 1 15)
    #(1 0 20)
    #(0 6 0)
    #(0 5 5)
    #(0 4 10)
    #(0 3 15)
    #(0 2 20)
    #(0 1 25)
    #(0 0 30) "