我只是在玩一些纯Ruby来获得更好的理解,并试图找到一个数字的素数,而不仅仅是使用素数宝石,我知道这一点,但我写这一切都是为了理解,而不是解决问题本身。
我写了以下代码:
class LargestPrimeFactor
# goal: find largest prime factor of 10 to start
attr_accessor :factors_list, :prime_factors, :idx, :below_n, :half_num
def initialize(below_n)
@below_n = below_n
@half_num = (below_n/2).floor
@idx = 2
@factors_list = []
@prime_factors = []
end
def prime_checker
sorted_list = factors_list.sort
sorted_list_length = sorted_list.length
puts "Sorted list of factors so far: #{sorted_list}"
sorted_list.combination(2) do |el, others|
if !prime_factors.include?(el) && others % el == 0
prime_factors << el
end
end
puts "Prime checker returned: #{prime_factors}"
end
def factors
congruent = (below_n % idx == 0)
not_listed = !factors_list.include?(idx)
number_candidate = idx
factors_list_length = factors_list.length
if congruent && not_listed && number_candidate
factors_list << number_candidate
puts "#{idx}"
puts "#{below_n}"
puts "why nil? #{below_n.divmod(idx)[0]}"
tmp = below_n.divmod(idx)[0]
idx = tmp #return number of times it divides in
puts "idx now: #{idx}"
elsif factors_list_length > 0 && factors_list[-1] - idx < 0
primes = prime_checker
puts "Prime factors: #{primes}"
puts "COMPLETE"
else
idx += 1
end
end
def find_primes
(1..half_num).each do |el|
factors
end
end
end
p = LargestPrimeFactor.new(below_n=10)
p.find_primes
但是,当我运行ruby largest_prime_factor.rb
时,我会得到以下输出错误:
2
10
why nil? 5
idx now: 5
Traceback (most recent call last):
5: from largest_prime_factor.rb:65:in `<main>'
4: from largest_prime_factor.rb:56:in `find_primes'
3: from largest_prime_factor.rb:56:in `each'
2: from largest_prime_factor.rb:57:in `block in find_primes'
1: from largest_prime_factor.rb:46:in `factors'
largest_prime_factor.rb:46:in `-': nil can't be coerced into Integer (TypeError)
我很困惑,因为我认为idx
会在第46行被设置为5
,但我以某种方式将其解释为nil
。关于如何在此方法中访问和设置此变量,我缺少什么?
谢谢!
Silvio Mayolo未解释错误
更改实例变量的问题——只是其中一个问题。但原因是另一个
例如,此代码:
class Foo
attr_accessor :bar
def initialize
@bar = 0
end
def baz
p x
10.times do
if bar < 6
@bar += 1
end
end
end
end
Foo.new.baz
将提高
undefined local variable or method `x'
但是这个代码:
class Foo
attr_accessor :bar
def initialize
@bar = 0
end
def baz
10.times do
if bar < 6
x = 1
@bar += 1
else
p x
end
end
end
end
Foo.new.baz
将打印
nil
nil
nil
nil
所以代码中的factors_list[-1] - idx < 0
会引发错误。局部变量idx
已声明,但未初始化,因为这些if
分支未执行
我很惊讶你的问题为什么被否决了。读者还没有弄清楚这个问题的感觉,以及Silvio Mayolo
您已经为@idx
声明了读取器,但没有声明写入器,因此当idx
工作并返回实例变量@idx
时,您无法对其进行写入。
直接写入实例变量(@idx = 5
(,或者创建写入程序(attr_accessor :idx
(并写入self.idx
(self.idx = 5
(。请注意,在后一种情况下,需要显式self
,这样就不会意外地生成一个同名的新局部变量。
您的idx += 1
行也需要进行类似的更新,以及尝试写入访问器的任何其他位置。