豊福@パパイヤです。
下のような剰余系のプログラムを書いて一応動くの
ですがもっとうまい方法を教えて下さい。
(1) 元の +,-,*,/ を使って *,/ を再定義しているの
ですが、元の +,-,*,/ を alias して使っているので
例えば x * b - y * a を x.ml(b).mn(y.ml(a)) と
書くように非常に可読性が悪くなっています。
(2) 最初は +,- も再定義していたのですが
for i 1..100 というのではまりました。i を増加
していくのにも再定義した + が使われるのですね。
当り前ですが。これはしょうがないだろうな。
# 剰余系での演算
# 合成数のケースはちょっと面倒なので後まわし
$mod = 0
def modulo(n)
$mod = n.abs
end
class Fixnum
alias pl +
alias mn -
alias ml *
alias dv /
# def + (other); super; end
# def - (other); super; end
def * (other); super; end
def / (other); super; end
def divmod(other)
x = self.dv(other)
# y = self - x * other
y = self.mn(x.ml(other))
return x, y
end
end
class Bignum
alias pl +
alias mn -
alias ml *
alias dv /
# def + (other); super; end
# def - (other); super; end
def * (other); super; end
def / (other); super; end
def divmod(other)
x = self.dv(other)
# y = self - x * other
y = self.mn(x.ml(other))
return x, y
end
end
class Integer
def mod
if ($mod == 0)
return self
else
void, x = self.divmod($mod)
x = x.pl($mod) if (x < 0)
return x
end
end
def inv
x = self
y = $mod
klist = []
void, a = x.divmod(y)
a = a.pl(y) if (a < 0)
b = y
while b != 0
k, a = a.divmod(b)
klist.push(k)
a, b = b, a
end
klist.pop
a, b = 1, 0
while (k = klist.pop) do
# a, b = k * a + b, a
a, b = k.ml(a).pl(b), a
end
# x * b - y * a
if (x.ml(b).mn(y.ml(a)) < 0)
#a = y - a
b = y.mn(b)
end
return b
end
#def +(other)
# self.pl(other).mod
#end
#def -(other)
# self.mn(other).mod
#end
def *(other)
self.ml(other).mod
end
def /(other)
if ($mod == 0)
self.dv(other)
else
self.ml(other.inv).mod
end
end
end
---
豊福@パパイヤ
unbound / papaya.juice.or.jp
toyofuku / juice.or.jp