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.
>
> class Fixnum
> def has_friend?
> t1, t2 = 1, 1
> 2.upto(self / 2) {|i| t1 += i if self % i == 0}
> 2.upto(t1 / 2) {|i| t2 += i if t1 % i == 0}
> return self == t2 && self != t1
> end
> def friend
> t1, t2 = 1, 1
> 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
--
Paul Lutus
http://www.arachnoid.com