sempsteen wrote:
Yep, now i know that my Hash example is a different matter.
The fix:
change ‘has_answer’ to store the answer (privately) after calculating it
and ‘answer’ to simply retrieve that answer if it has been created.
Where do you suggest to store the value for my amicable numbers example?
Use my previously posted code as a starting point, the one that uses a
precalculated hash of divisor sums.
Create an instance of your class and accept a value for maximum number
if
the user offers one. Precalculate the sums of divisors as you initialize
the class, up to this provided maximum number, or a default value.
If the user provides an argument that is our of range of the
precalculated
values, just calculate additional values and add them to the existing
hash,
then return the result to the user.
2.upto(self / 2) {|i| t1 += i if self % i == 0}
2.upto(t1 / 2) {|i| t2 += i if t1 % i == 0}
return t1 if self == t2 && self != t1
end
end
1.upto(1000) {|i| print i, “\t<->\t”, i.friend, “\n” if i.has_friend?}
Please abandon this code. It is extremely inefficient.
I want a “has_friend?” method and “friend” method. One for searching
for the existing of given number, other one is for getting the value
of the friend of that number. And i want those methods inside “Fixnum”
class structure, like as instance methods.
No, you do not. You want to write a separate class for handling this
specialized kind of problem, not part of Fixnum. And yo do not want to
recalculate the entire divisor set over again for each entered argument.
when i call has_friend? method it will store its value to some kind of
variable, but return true or false and, when i call friend method it
will get the stored value.
But what must be that some kind of variable that holds the value?
A hash table, as in my posted example. And you do not want to make
this
amicable detector capability part of Fixnum, any more than you would
want
to make a numerical integral solver part of Fixnum – it’s just not
appropriate to be included in the class.
#!/usr/bin/ruby -w
class Amicable
def initialize(max = 1000)
@max = 2
fill_hash(max)
end
def fill_hash(max)
@hash ||= {}
if(max > @max)
2.upto(max) do |i|
sum = 1
2.upto(i/2) do |j|
sum += j if (i % j) == 0
end
@hash[i] = sum
end
@max = max
end
end
def comp_amicable(n)
fill_hash(n)
q = @hash[n]
return @hash[n] if n == @hash[q] && n != q
return false
end
def has_friend?(n)
return comp_amicable(n) != false
end
def friend(n)
return comp_amicable(n)
end
end
test the class:
max = 10000
amic = Amicable.new(max)
2.upto(max) do |i|
j = amic.friend(i)
puts “#{i} <-> #{j}” if j
end
Output:
220 <-> 284
284 <-> 220
1184 <-> 1210
1210 <-> 1184
2620 <-> 2924
2924 <-> 2620
5020 <-> 5564
5564 <-> 5020
6232 <-> 6368
6368 <-> 6232