A cute way to reduce a fraction?

Hello,

I’m trying to find a pretty way to reduce a fraction. Assuming I have two
arrays, num' andden’, containing the prime factors of the numerator and
the denomenator, I’d like some nice way to remove identical numbers and thus
reduce the fraction. So it would look like this:

num = [2, 2, 3] # 12
den = [2, 3] # 6

…your pretty ruby here…

num # --> [2]
den # --> []

I tried some stuff with each_with_index and deleting from the arrays when I
find a match, but deleting elements from an array you are each’ing is not
pretty. Every solution I come up with seems to have too much going on.
There’s got to be a pretty Ruby way to do this, right?

Chris

Hello,

I’m trying to find a pretty way to reduce a fraction. Assuming I have two
arrays, num' and den’, containing the prime factors of the numerator and
the denomenator, I’d like some nice way to remove identical numbers and thus
reduce the fraction. So it would look like this:

num = [2, 2, 3] # 12
den = [2, 3] # 6

…your pretty ruby here…

Okay, not all that pretty, but

def enc(a)
h = Hash.new(0)
a.map {|n| “#{n}.#{h[n]+=1}”}
end

def diff(a,b)
(enc(a) - enc(b)).map {|i| i.to_i}
end

num, den = diff(num, den), diff(den, num)

num # → [2]
den # →

You’re right, there should be a simpler way!

martin

···

Chris Pine nemo@hellotree.com wrote:

Knew I was overcomplicating it!

den.each_index{|i|
if (f = num.index(den[i]))
num[f] = den[i] = nil
end
}

num, den = num.compact, den.compact
p num, den

martin

···

Martin DeMello martindemello@yahoo.com wrote:

Chris Pine nemo@hellotree.com wrote:

Hello,

I’m trying to find a pretty way to reduce a fraction. Assuming I have two
arrays, num' and den’, containing the prime factors of the numerator and
the denomenator, I’d like some nice way to remove identical numbers and thus
reduce the fraction. So it would look like this:

num = [2, 2, 3] # 12
den = [2, 3] # 6

…your pretty ruby here…

If you hadn’t already factorized them (or even perhaps if you have!),
you’re better off computing the gcd of numerator and demoninator and
dividing if not 1. gcd is very fast.

I had to do fractional arithmetic for an integer 2-d graphics package
once, and needed to find fractional approximations that wouldn’t
cause integer overflow during transform. There’s a surprisingly easy
algorithm for computing a fractional approximation for a real number
to within an allowed error margin, I’ll look it up if anyone’s
interested. I just iterated the algorithm until the approximation
generated a numerator that was too large, then used the previous
fraction. All a bit pointless now, actually slower than using
floating point because the integer unit is tied up with fractions
and can’t do the other things (array indexing etc) if needs to do.

Clifford.