09

Task

Result

有理数クラスRatioと複素数クラスCompを定義しました。コードは巻末に示しました。 以下のように実行し、結果を得ました。

puts Ratio.new(2, 3) + Ratio.new(1, 3) puts Ratio.new(4, 3) - Ratio.new(1, 3) puts Ratio.new(3, 1) * Ratio.new(1, 3) puts Ratio.new(1, 3) / Ratio.new(1, 3) puts Comp.new(2, 3) + Comp.new(1, 3) puts Comp.new(4, 3) - Comp.new(1, 3) puts Comp.new(3, 1) * Comp.new(1, 3) puts Comp.new(1, 3) / Comp.new(1, 3)
1/1 1/1 1/1 1/1 3 + 6i 3 + 0i 0 + 10i 1 + 0i

Consideration

まず、Ratioクラスに対し、各四則演算と,@a, @bへのgetter関数c, dを定義しました。 名前をa, b, c, dと公式にあわせたり,*= などを用いることで、コードが読みやすくなりました。 また、例では各演算ごとにインスタンス化していて、最適化できていないと考えられるので、 initialize内にあった処理を別の関数bindにうつし、各演算ではselfを返すようにしました。 また、Compクラスの乗法、除法ではを直接代入すると値がおかしくなるので、 計算結果は変数a, bへ一旦代入し、あとから @a, @bを指定するようにしました。

Ref

class Ratio def initialize(a, b=1) @a = a @b = b self.bind end def bind if @b == 0 then @a = 1; return end if @a == 0 then @b = 1; return end if @b < 0 then @a = -@a; @b = -@b end g = gcd(@a.abs, @b.abs); @a = @a/g; @b = @b/g return self end def c return @a end def d return @b end def to_s return "#{@a}/#{@b}" end def +(r) @a = @a*r.d + @b*r.c @b *= r.d return self.bind end def -(r) @a = @a*r.d - @b*r.c @b *= r.d return self.bind end def *(r) @a *= r.c @b *= r.d return self.bind end def /(r) @a *= r.d @b *= r.c return self.bind end def gcd(x, y) while true do if x > y then x = x % y; if x == 0 then return y end else y = y % x; if y == 0 then return x end end end end end class Comp def initialize(a, b=1) @a = a @b = b end def c return @a end def d return @b end def to_s return "#{@a} + #{@b}i" end def +(r) @a += r.c @b += r.d return self end def -(r) @a -= r.c @b -= r.d return self end def *(r) a = @a*r.c - @b*r.d b = @b*r.c + @a*r.d @a = a; @b = b return self end def /(r) a = (@a*r.c + @b*r.d) / (r.c**2 + r.d**2) b = (@b*r.c + @a*r.d) / (r.c**2 + r.d**2) @a = a; @b = b return self end end