59 lines
1.8 KiB
Lua
59 lines
1.8 KiB
Lua
function gcd(a,b) return a == 0 and b or gcd(b % a, a) end
|
|
|
|
do
|
|
local function coerce(a, b)
|
|
if type(a) == "number" then return rational(a, 1), b end
|
|
if type(b) == "number" then return a, rational(b, 1) end
|
|
return a, b
|
|
end
|
|
rational = setmetatable({
|
|
__add = function(a, b)
|
|
local a, b = coerce(a, b)
|
|
return rational(a.num * b.den + a.den * b.num, a.den * b.den)
|
|
end,
|
|
__sub = function(a, b)
|
|
local a, b = coerce(a, b)
|
|
return rational(a.num * b.den - a.den * b.num, a.den * b.den)
|
|
end,
|
|
__mul = function(a, b)
|
|
local a, b = coerce(a, b)
|
|
return rational(a.num * b.num, a.den * b.den)
|
|
end,
|
|
__div = function(a, b)
|
|
local a, b = coerce(a, b)
|
|
return rational(a.num * b.den, a.den * b.num)
|
|
end,
|
|
__pow = function(a, b)
|
|
if type(a) == "number" then return a ^ (b.num / b.den) end
|
|
return rational(a.num ^ b, a.den ^ b) --runs into a problem if these aren't integers
|
|
end,
|
|
__concat = function(a, b)
|
|
if getmetatable(a) == rational then return a.num .. "/" .. a.den .. b end
|
|
return a .. b.num .. "/" .. b.den
|
|
end,
|
|
__unm = function(a) return rational(-a.num, -a.den) end}, {
|
|
__call = function(z, a, b) return setmetatable({num = a / gcd(a, b),den = b / gcd(a, b)}, z) end} )
|
|
end
|
|
|
|
print(rational(2, 3) + rational(3, 5) - rational(1, 10) .. "") --> 7/6
|
|
print((rational(4, 5) * rational(5, 9)) ^ rational(1, 2) .. "") --> 2/3
|
|
print(rational(45, 60) / rational(5, 2) .. "") --> 3/10
|
|
print(5 + rational(1, 3) .. "") --> 16/3
|
|
|
|
function findperfs(n)
|
|
local ret = {}
|
|
for i = 1, n do
|
|
sum = rational(1, i)
|
|
for fac = 2, i^.5 do
|
|
if i % fac == 0 then
|
|
sum = sum + rational(1, fac) + rational(fac, i)
|
|
end
|
|
end
|
|
if sum.den == sum.num then
|
|
ret[#ret + 1] = i
|
|
end
|
|
end
|
|
return table.concat(ret, '\n')
|
|
end
|
|
print(findperfs(2^19))
|