今日のプログラムと、自分にとっての調和

自分が小学生のころからの小さな悲願であった問題を、毎日解決できるコードを作成しました。

http://ja.doukaku.org/90/lang/ruby/
の kenaxt 様のコードを拝借し、手を加えます。

def divComb(base_ary)
  s_base = base_ary.sum
  h = {}
  req = [[1]*10]
  while req != []
    w1 = req.shift
    next if h[w1]
    s = w1.sum
    c, l = base_ary.dup, s_base
    w1.map {|i|i.to_s.scan(/./) {c[$&.to_i]+=1; l += 1}}
    h[w1] = (c.sort != w1 ? c.sort : c)
    if s<=l
      (0..9).each {|i|w = w1.dup; w[i] += 1; req << w.sort}
    end
  end
  h
end

def callDivComb
  flag = false
  today_str = Time.now.strftime("%Y/%#m/%#d")
  divComb(make_base(today_str)).each {|c,x|
    if c == x.sort
      flag = true
      puts "This sentence includes"
      x.each_with_index do |n, i|
        puts "#{n} of #{i}s,"
      end
      puts "in #{today_str}."
      puts
    end
  }
  unless flag
    puts "There is no sentence you want today. Sorry!"
  end
end

def make_base(str)
  ary = []
  (0..9).each do |n|
    ary[n] = str.count(n.to_s) + 1
  end
  ary
end

class Array
  def sum
    self.inject(0) {|r,i|r += i}
  end
end

callDivComb

動かしますと、

This sentence includes
3 of 0s,
4 of 1s,
5 of 2s,
3 of 3s,
4 of 4s,
2 of 5s,
2 of 6s,
1 of 7s,
1 of 8s,
2 of 9s,
in 2009/6/14.

「2009年6月14日現在、この文には、0が3個、1が4個、2が5個、3が3個、4が4個、5が2個、6が2個、7が1個、8が1個、9が2個存在します。」

うん。まさしく美。調和。

この種類の問題は、昔平成教育委員会で、ピーター・フランクル氏の出題として出会った記憶があります。明確なアルゴリズムによる解法も提示されたように思うのですが忘れてしまいました。

ちなみにTime#strftime("%Y/%#m/%#d") のところで"%Y/%m/%d"として 2009/06/14 とすると解がありませんでした。
なんとなくな感覚として0が多いと解がないときが多いようです。確かにシステム上、0の数はすぐ確定するのですが、その数があまり大きすぎるといけないのでしょうか?