RosettaCodeData/Task/Elliptic-curve-arithmetic/Pluto/elliptic-curve-arithmetic.pluto
2026-04-30 12:34:36 -04:00

59 lines
1.7 KiB
Text

$define C = 7
class pt
static function zero() return new pt(math.inf, math.inf) end
static function from_num(n) return new pt(math.cbrt(n * n - C), n) end
function __construct(public x, public y) end
function iszero() return math.abs(self.x) > 1e20 end
function double()
if self:iszero() then return self end
local l = 3 * self.x * self.x / (2 * self.y)
local t = l * l - 2 * self.x
return new pt(t, l * (self.x - t) - self.y)
end
function __unm() return new pt(self.x, - self.y) end
function __add(other)
assert(other instanceof pt, "argument must be a pt object")
if self.x == other.x and self.y == other.y then return self:double() end
if self:iszero() then return other end
if other:iszero() then return self end
local l = (other.y - self.y) / (other.x - self.x)
local t = l * l - self.x - other.x
return new pt(t, l * (self.x - t) - self.y)
end
function __mul(n)
assert(math.type(n) == "integer", "argument must be an integer")
local r = pt.zero()
local p = self
local i = 1
while i <= n do
if (i & n) != 0 then r += p end
p = p:double()
i <<= 1
end
return r
end
function __tostring()
return self:iszero() ? "Zero" : string.format("(%0.3f, %0.3f)", self.x, self.y)
end
end
local a = pt.from_num(1)
local b = pt.from_num(2)
local c = a + b
local d = -c
print($"a = {a}")
print($"b = {b}")
print($"c = a + b = {c}")
print($"d = -c = {d}")
print($"c + d = {c + d}")
print($"a + b + d = {a + b + d}")
print($"a * 12345 = {a * 12345}")