各位の数字の和を求めるメソッドをテスト駆動開発する(Project Euler 問20)

スポンサーリンク

今回の問題

Factorial digit sum

n! means n × (n − 1) × … × 3 × 2 × 1

For example, 10! = 10 × 9 × … × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.

Find the sum of the digits in the number 100!

n × (n – 1) × … × 3 × 2 × 1 を n! と表す.

例えば, 10! = 10 × 9 × … × 3 × 2 × 1 = 3628800 となる.
この数の各桁の合計は 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27 である.

では, 100! の各位の数字の和を求めよ.

書いた内容

テストの作成と仮メソッド定義

Minitest を用いて、階乗の始点となる数字を引数にもつ
factorial_digit_sumメソッドのテストを仮で記載しました。

まずはテストが通るようにメソッド自体も返り値を直接 1 と記載しました。

require 'minitest/autorun'
require './problem'

require 'minitest/reporters'
Minitest::Reporters.use!

class ProblemTest < Minitest::Test
  def test_factorial_digit_sum
    assert_equal 1, factorial_digit_sum(10)
  end
end
def factorial_digit_sum(number)
  1
end

階乗の計算結果を返すテストを通す

問題文で 10 の階乗が 3628800 と書かれているので
テストもその内容に変更します。

require 'minitest/autorun'
require './problem'

require 'minitest/reporters'
Minitest::Reporters.use!

class ProblemTest < Minitest::Test
  def test_factorial_digit_sum
    assert_equal 3628800, factorial_digit_sum(10)
    assert_equal 6, factorial_digit_sum(3)
    assert_equal 120, factorial_digit_sum(5)
  end
end

downtoメソッドとinjectメソッドを用いて
階乗結果が返るようにメソッド内容を変更してテストを通します。

def factorial_digit_sum(number)
  number.downto(1).inject(&:*)
end

階乗結果の各桁の和を返すテスト

問題文で 10 の階乗 3628800 の各桁の合計が 27 と書かれているので
テストもその内容に変更します。

require 'minitest/autorun'
require './problem'

require 'minitest/reporters'
Minitest::Reporters.use!

class ProblemTest < Minitest::Test
  def test_factorial_digit_sum
    assert_equal 27, factorial_digit_sum(10)
    assert_equal 6, factorial_digit_sum(3)
    assert_equal 3, factorial_digit_sum(5)
  end
end

階乗の計算結果をローカル変数 factorial_number という変数に代入し
String型に変換した上でcharsメソッドで各桁に分解し、
再度Integer型の配列に組み替えて足し上げてテストを通します。

def factorial_digit_sum(number)
  factorial_number = number.downto(1).inject(&:*)
  factorial_number.to_s.chars.map(&:to_i).inject(:+)
end

puts factorial_digit_sum(100)
#=> 648

最終的な答えは 648 と出すことが出来ました。

※問20ブランチのプルリクエスト

          
    

スポンサーリンク

  
Scroll Up