分数化简的 Ruby 版


虽然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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值