[AtCoder]ABC083B – Some Sums[Ruby]

プログラミング

問題

問題文

1 以上 N 以下の整数のうち、10進法での各桁の和が A 以上 B 以下であるものの総和を求めてください。


入出力例

入力例
20 2 5
出力例
84
20以下の整数のうち、各桁の和が 2 以上 5 以下なのは 2,3,4,5,11,12,13,14,20です。
これらの合計である84を出力します。

自分の回答

def somesums(a, b, c)
  result = []
  remainders = []
 
  (1..a).each do |num|
    number = num
    number_digits = num.to_s.length
    number_digits.times do
      remainder = num % 10.to_f
      remainders.push(remainder)
      num = num/10
    end
    
    if b <= remainders.inject(:+) && remainders.inject(:+) <= c
      result.push(number)
    end
    remainders = []
  end
  p result.inject(:+)
end
 
a,b,c=gets.chomp.split(" ").map(&:to_i);
somesums(a, b, c)

ハマった点は17行目にsums=[]を入れるのを忘れていたところです。そのため、sumsに前の値で求めたあまりが入ったままになって、正しい結果が出ませんでした。

また、AtCoderでは、rubyの実行バージョンが2.3.3となっています。そのため、sumメソッドが使えないのも注意する点です。そうとは知らずに、自分の環境下では動くのに、提出したらエラーとなって得点が0となってしまいました。rubyのバージョンには気をつけましょう。

コードテストというタブをひらけば、そこでコードをテストすることもできるのでそれを使うのもいいと思います。

もっとよくする

def somesums(a, b, c)
  result = 0
  (1..a).each do |num|
    remainders = 0
    number = num
    number_digits = num.to_s.length
    number_digits.times do
      remainders += num % 10
      num = num/10
    end
    if b <= remainders && remainders <= c
      result += number
    end
  end
  p result
end
 
a,b,c=gets.chomp.split(" ").map(&:to_i);
somesums(a, b, c)

他の方の答えを参考にして、修正してみました。主な修正点は元々は配列にpushして後から.inject(:+)として、数値の合計を求めていたところを、自己代入演算子+=を用いて、簡略化したところです。

これによって、コードも短くなり、実行時間も31ms=>13msまで短くなりました。こういうときは、自己代入演算子を使おうと思います。

自己代入演算子

変数 += 式 => 変数 = 変数 + 式 
変数 -= 式 => 変数 = 変数 - 式 
変数 *= 式 => 変数 = 変数 * 式 
変数 /= 式 => 変数 = 変数 / 式 
変数 %= 式 => 変数 = 変数 % 式 
変数 **= 式 => 変数 = 変数 ** 式

タイトルとURLをコピーしました