るびらな!

RubyをLearnする人の勉強記録。(超)弩(級の)素人なので、誰かダメさがわかる人に罵ってもらったりして、少しずつ知見を広げたいと思っています。

ITP1_3_D How Many Divisors?

ここも押していただけると嬉しいです #=> にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ Rubyへ にほんブログ村 IT技術ブログ Ruby on Railsへ

AOJをRubyで解くのも、とうとう第11日目。今日も楽しく書いていきたいと思います。

本日のお題はこちら #=>
約数の数 | プログラミング入門 | Aizu Online Judge

問題

約数の数

3つの整数 a、b、c を読み込み、a から b までの整数の中に、c の約数がいくつあるかを求めるプログラムを作成してください。


Input

a、b、c が1つの空白区切りで1行に与えられます。


Output

約数の数を1行に出力してください。

なるほど、約数の数、と…

しかし、数に規則性がないと総当たり的になって処理が遅くなりそうだけど、

とりあえずそれでやってみようかな。

自分のコード

a,b,c = gets.split.map(&:to_i)
i = a
cnt = 0
while i<=b
    if ( c % i == 0 )
        cnt += 1
    end
 
    i += 1
end
 
puts cnt

恥ずかしいことに、後から見直したらiが完全に不要でした…

aのまま使っておけ!っていう。

でも、提出しちゃったコードを素直に曝して、恥ずかしい思いをした方がたぶん改善も早い…よね??


他の人のコード

さすがに

一番短い人

a,b,c=gets.split.map &:to_i
s=0
(a..b).map{|i|s+=1[c%i]}
p s

(a..b).map~っていうのは確かに賢い書き方だなぁ、という感じです。

総当たり的に処理をするときは使えますね。

class Primeを使った人

今は既に使用は非推奨になっていますが、疑似素数を使って解いた人もいますね。

require 'prime'
 
class Integer
  def divisor_list
    return [] if self <= 0
    return [1] if self == 1
 
    prime_division.map{|e| [*(0..e.last)].map{|v| e.first ** v }}.inject{|res, e| res.map{|t| e.map{|v| t * v}}.flatten}.sort
  end
end
 
class Array
  def upper_bound(val)
    a = 0
    b = size
 
    while a < b
      c = (( a + b ) / 2 ).to_i
 
      if val < at(c)
        b = c
      else
        a = c + 1
      end
    end
 
    b
  end
 
  def lower_bound(val)
    a = 0
    b = size
 
    while a < b
      c = (( a + b ) / 2 ).to_i
 
      if val <= at(c)
        b = c
      else
        a = c + 1
      end
    end
     b
  end
end
 
class Solver
  def initialize
    a, b, c = gets.chomp.split(' ').map(&:to_i)
 
    divisor_list = c.divisor_list
 
    n = divisor_list.lower_bound(a)
    m = divisor_list.upper_bound(b)
 
    puts m - n
  end
end
 
Solver.new

感想

色んな解き方をしていますが、概ね総当たり的に解く感じで、

あとは繰り返し構文はお好きな感じで、という人が多かったですね。

全体には、Cから勉強を始めた人が多いのか、for文が多い感じでした。

a.upto(b)とかのほうがRubyらしいのかな?