虽然Ruby 已有Rational 类做这件事情,还是想试一试。
刚开始我以为通分以后分子、分母分别除以原来分母的最大公因数就可以了
7/6 + 5/8 = (7×8+5×6)/(6×8) = (86/ gcd(6, 8)) / (48/ gcd(6, 8)) = 43/24
还为此证明了老半天。
后来我们一高人给了一个例子:
7/18 + 11/30 = (7×30+11×18) / (18×30) = (408/ gcd(18, 30))/(540/ gcd(18, 30)) = 68/90 ≠ 34/45
即68/90不是最简方式。
至于他是怎么找到这个反例的?其实也很简单,他利用了odd + odd = even
就是通分后的分子在除以原来分母的最大公因数后变成两个奇数之和,并让通分后的分母还余下一个二(即为偶数)。这样分子、分母就各余一个2。
比如先想好 3× x + 7× y (之所以选择3和7是因为它们是质数,这样就可以保证通分之前它们都是既约的)
x, y要满足x/even, y/even 都是奇数,且gcd(x, y) = even
我选even = 4, x = 4×3, y = 4×5,
这样(3×(4×3) + 7×(4×5)) / 4 与 ((4×3)×(4×5)) / 4 都是偶数。
=_=||
汗颜啊,为什么高手这么多,连我身边都有好多!
P.S.
- 我就说为什么没有看到gcd 和加法或者乘法扯上关系(Goldbach猜想与加法搭了点边,至今没人证出来),比如gcd(a + b, c) = ?。唯一有一条“The gcd is a multiplicative function in the following sense: if a1 and a2 are relatively prime, then gcd(a1·a2, b) = gcd(a1, b)·gcd(a2, b).” 还得互质。
- 千万不要想都不想就去证明那些看似正确的定理。
- 放心,下面的程序还是有保证的(因为是按照定义去写的)。
require 'mathn' class Fraction attr_accessor :numerator attr_accessor :denominator def initialize(num = 1, deno = 1) @numerator, @denominator = num, deno end def reduce gcd = @numerator.gcd2(@denominator) #print "(#{@numerator}, #{@denominator}) = #{gcd}/n" @numerator /= gcd; @denominator /= gcd; #print "reduce: #{@numerator} / #{@denominator}/n" end def +(rhs) self.reduce rhs.reduce sum = Fraction.new(@numerator*rhs.denominator + @denominator*rhs.numerator, @denominator*rhs.denominator) sum.reduce return sum end def -(rhs) self.reduce rhs.reduce diff = Fraction.new(@numerator*rhs.denominator - @denominator*rhs.numerator, @denominator*rhs.denominator) diff.reduce return diff end def *(rhs) self.reduce rhs.reduce prod = Fraction.new(@numerator*rhs.numerator, @denominator*rhs.denominator) prod.reduce return prod end def /(rhs) self.reduce rhs.reduce quot = Fraction.new(@numerator*rhs.denominator, @denominator*rhs.numerator) quot.reduce return quot end def myprint self.reduce print "#{@numerator}" print " / #{@denominator}" if @denominator != 1 print "/n" end end a = Fraction.new(15, 12) b = Fraction.new(18, 16) c = Fraction.new d = Fraction.new e = Fraction.new f = Fraction.new c = a + b d = a - b e = a * b f = a / b c.myprint d.myprint e.myprint f.myprint