simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

Rubyで全ての約数を出すメソッドを作った

「How Many Divisors?」
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_3_D

AOJの問題を解いてて「約数の配列だして、upper_boundとlower_boundをとれば終わりやな」と思ったのですが、Rubyに今の要素全部無かったので、作りました。

require 'prime'

class Array
  def upper_bound(x)
    bsearch_index { |v| v > x }
  end

  def lower_bound(x)
    bsearch_index { |v| v >= x }
  end
end

class Integer
  def divisor_list
    return [] if self <= 0
    return [1] if self == 1

    prime_division.map.with_index { |(base, k), i|
      s = i.zero? ? 0 : 1
      (s..k).map { |n| base ** n }
    }.inject { |res, e| res + res.flat_map { |t| e.map { |v| t * v } } }.sort
  end
end

a, b, c = gets.split.map(&:to_i)
list = c.divisor_list

x = list.upper_bound(b) || list.size
y = list.lower_bound(a) || list.size

puts x - y

Array#bsearch_index を使うことで簡単に実装出来た。