ITP1_3_D How Many Divisors?
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らしいのかな?