作者: HIDAKA Takahiro
日時: 2002/5/06(02:28)
 ひだかです。

閑舎 <raku@...> wrote:

>  練習のために、ruby 版を何とか作ってみました。たぶん本当はもう少しスマー
> トになると思います。特に 6 行目。
> 
>  また、eval(" ")、つまり nil らしいのですが、は Perl なら数値として評価
> されるコンテクストに置くと 0 になるのですが、Ruby だとそうならないような
> ので、ちょっと面食らいました。

 Integer(nil) は 0 になります。

> --^ dice.rb
> DICE = "8 4 2 1".split(/ /)

 DICE = %w(8 4 2 1)

で、String を要素に持つ Array を作ることができます。

> l = DICE.length
> (2**l).times {|i|
>   exp = ""
>   k = 0
>   for j in sprintf(sprintf("%%0%db", l), i).split(//)

  sprintf("%0*b", l, i) で充分ですよね?

>     exp += (j == "1") ? ("+" + DICE[k]): "  "
>     k = k + 1
>   end
>   print exp, "=", ((/^\s+$/ =~ exp)? 0: eval(exp)), "\n"
> }
> --$

 ということでリスト操作で Array#combination を
書いてみました。

--^ dice2.rb
#!/usr/local/bin/ruby

dice = [8,4,2,1]

class Array
  def combination(&block)
    if self.length == 0 
      yield []
    else
      self[1..-1].combination do | c |
        yield c
        yield c + [self[0]]
            # ここを c << self[0] と破壊的メソッドで書くとはまります。。
      end
    end
  end
end

dice.combination do | a |
  exp = a.join(' + ')
  puts "#{exp} = #{Integer(eval(exp))}"
end
--$

 ちょっとだけ「Rubyプログラミング入門」を参照したんですけど
それそのものは使えなかったので結局普通に書きました。

 こういうのは scheme 担当さんに任せたほうがよかったかな..

-- 
ひだかたかひろ  cv8t-hdk@...-net.or.jp