Created
November 18, 2015 03:59
-
-
Save plonk/f05b0f6a411d0d7f6d2b to your computer and use it in GitHub Desktop.
アリコット数列を求めるプログラム
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# アリコット数列を求めるプログラム | |
# | |
# アリコット数列はある項が前の項の真の約数の和になっているような数列で | |
# す。 | |
# | |
# 276で始まるアリコット数列が有限かどうかはわかっていないらしいです。 | |
require 'prime' | |
def aliquot_function(n) | |
factors = n.prime_division | |
numerator = factors.map { |p, k| p**(k+1) - 1 }.reduce(1, :*) | |
denominator = factors.map { |p, _| p - 1 }.reduce(1, :*) | |
return numerator/denominator - n | |
end | |
raise unless aliquot_function(276) == 396 | |
def period(n) | |
peri = 1 | |
m = n | |
until (m = aliquot_function(m)) == n | |
peri += 1 | |
end | |
return peri | |
end | |
def main | |
# アリティーチェック | |
if ARGV.size != 1 | |
puts "Usage: #{$0} NUMBER" | |
exit 1 | |
end | |
# サニティーチェック | |
arg = ARGV[0] | |
if arg !~ /\A[1-9]\d*\z/ | |
puts "argument error: '#{arg}' is not a number" | |
exit 1 | |
end | |
# メインロジック | |
number = arg.to_i | |
puts "#{number}のアリコット数列を求めます。" | |
seen = {number=>true} | |
puts "#{number}, " | |
loop do | |
number = aliquot_function(number) | |
puts "#{number}, " | |
if number == 0 | |
puts "以上。長さ#{seen.size + 1}。" | |
break | |
elsif seen[number] | |
peri = period(number) | |
puts "以下周期#{peri}の繰り返し…" | |
break | |
end | |
seen[number] = true | |
end | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment