友愛数、完全数、過剰数、不足数、回文数 色んな数のプログラムを作ってみた


何かQiitaに投稿できそうなネタは無いかなーーとフォルダを漁っていると、
6年以上前にProjectEulerちょっとやってみてた時のスクリプトを掘り起こしたので、
それを書きます

実行環境は下記になります。
ruby 2.6.3p62
macOS Catalina 10.15.6
zsh

約数を生成する

約数なんだったけという方は下記を参照下さい。
https://ja.wikipedia.org/wiki/約数

divisor.rb
def create_divisor (num)
    divisor_ary = Array.new
    partner_divisor_ary = Array.new

    if num < 1 then
        return nil
    elsif num == 1 then
        divisor_ary.push 1
    else
        i = 1
        partner_divisor = 0
        until i == partner_divisor do
            if num % i == 0 then
                divisor_ary.push i
                partner_divisor = num / i
                if partner_divisor != i then
                    partner_divisor_ary.unshift partner_divisor
                else
                    break
                end
            end
            i += 1
        end
        divisor_ary += partner_divisor_ary
    end

    return divisor_ary
end

class Integer
    def divisor
        return create_divisor(self)
    end
end

p 8.divisor
p 128.divisor
p 12345.divisor

実行結果は下記になります。

% ruby divisor.rb
[1, 2, 4, 8]
[1, 2, 4, 8, 16, 32, 64, 128]
[1, 3, 5, 15, 823, 2469, 4115, 12345]

※ 以下のコードで、
 約数生成するcreate_divisor関数の定義は省略してます。

友愛数を生成する

友愛数...リア充な良い名前だと思います。
自然数a,bとして、
・aの約数の和-a = b
 かつ、
・bの約数の和-b = a
となる時、a, bを友愛数というみたいです。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/友愛数

number_amicable.rb
class Integer
    def divisor
        return create_divisor(self)
    end
    def amicable
        amicable_number = nil

        if self < 1 then
            return amicable_number
        end

        divisor_ary = self.divisor
        divisor_ary.pop
        unless divisor_ary.empty? then
            partner_number = divisor_ary.inject(:+)
            if partner_number != self then
                partner_divisor_ary = partner_number.divisor
                partner_divisor_ary.pop
                if partner_divisor_ary.inject(:+) == self then
                    amicable_number = partner_number
                end
            end
        end
        return amicable_number
    end
end

p 220.amicable
p 284.amicable
p 17296.amicable
p 18416.amicable
p 200.amicable

実行結果は下記になります。

% ruby number_amicable.rb
284
220
18416
17296
nil

完全数か過剰数か不足数かを判定する

自然数aとして、
(1) 約数の総和 = a*2 の場合、 aは完全数[perfect number]。
(2) 約数の総和 > a*2 の場合、 aは過剰数[abundant number]。
(3) 約数の総和 < a*2 の場合、 aは不足数[deficient number]。
みたいです。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/完全数
https://ja.wikipedia.org/wiki/過剰数
https://ja.wikipedia.org/wiki/不足数

number_p_a_d.rb
class Integer
    def divisor
        return create_divisor(self)
    end
    def compare_divisor_total
        sum_divisor = self.divisor.inject(:+)
        sum_divisor -= self
        if sum_divisor > self then
            return "abundant number"
        elsif sum_divisor == self then
            return "perfect number"
        else
            return "deficient number"
        end
    end
end

p 496.compare_divisor_total
p 20.compare_divisor_total
p 15.compare_divisor_total
p 1.compare_divisor_total

実行結果は下記になります。

% ruby number_p_a_d.rb
"perfect number"
"abundant number"
"deficient number"
"deficient number"

回文数かどうかを判定する

回文数とは、上から読んでも下から読んでも同じ数になる数のことです。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/回文数

number_palindrome.rb
class Integer
    def palindrome?
        str = self.to_s
        if str[0, (str.length / 2).floor] == str.reverse[0, (str.length / 2).floor]
            return true
        else
            return false
        end
    end
end

p 341.palindrome?
p 121.palindrome?
p 3456543.palindrome?

実行結果は下記になります。

% ruby number_palindrome.rb
false
true
true

以上です。