Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
98
Task/Arithmetic-Rational/Nim/arithmetic-rational.nim
Normal file
98
Task/Arithmetic-Rational/Nim/arithmetic-rational.nim
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import math
|
||||
|
||||
proc `^`[T](base, exp: T): T =
|
||||
var (base, exp) = (base, exp)
|
||||
result = 1
|
||||
|
||||
while exp != 0:
|
||||
if (exp and 1) != 0:
|
||||
result *= base
|
||||
exp = exp shr 1
|
||||
base *= base
|
||||
|
||||
proc gcd[T](u, v: T): T =
|
||||
if v != 0:
|
||||
gcd(v, u mod v)
|
||||
else:
|
||||
u.abs
|
||||
|
||||
proc lcm[T](a, b: T): T =
|
||||
a div gcd(a, b) * b
|
||||
|
||||
type Rational* = tuple[num, den: int64]
|
||||
|
||||
proc fromInt*(x: SomeInteger): Rational =
|
||||
result.num = x
|
||||
result.den = 1
|
||||
|
||||
proc frac*(x: var Rational) =
|
||||
let common = gcd(x.num, x.den)
|
||||
x.num = x.num div common
|
||||
x.den = x.den div common
|
||||
|
||||
proc `+` *(x, y: Rational): Rational =
|
||||
let common = lcm(x.den, y.den)
|
||||
result.num = common div x.den * x.num + common div y.den * y.num
|
||||
result.den = common
|
||||
result.frac
|
||||
|
||||
proc `+=` *(x: var Rational, y: Rational) =
|
||||
let common = lcm(x.den, y.den)
|
||||
x.num = common div x.den * x.num + common div y.den * y.num
|
||||
x.den = common
|
||||
x.frac
|
||||
|
||||
proc `-` *(x: Rational): Rational =
|
||||
result.num = -x.num
|
||||
result.den = x.den
|
||||
|
||||
proc `-` *(x, y: Rational): Rational =
|
||||
x + -y
|
||||
|
||||
proc `-=` *(x: var Rational, y: Rational) =
|
||||
x += -y
|
||||
|
||||
proc `*` *(x, y: Rational): Rational =
|
||||
result.num = x.num * y.num
|
||||
result.den = x.den * y.den
|
||||
result.frac
|
||||
|
||||
proc `*=` *(x: var Rational, y: Rational) =
|
||||
x.num *= y.num
|
||||
x.den *= y.den
|
||||
x.frac
|
||||
|
||||
proc reciprocal*(x: Rational): Rational =
|
||||
result.num = x.den
|
||||
result.den = x.num
|
||||
|
||||
proc `div`*(x, y: Rational): Rational =
|
||||
x * y.reciprocal
|
||||
|
||||
proc toFloat*(x: Rational): float =
|
||||
x.num.float / x.den.float
|
||||
|
||||
proc toInt*(x: Rational): int64 =
|
||||
x.num div x.den
|
||||
|
||||
proc cmp*(x, y: Rational): int =
|
||||
cmp x.toFloat, y.toFloat
|
||||
|
||||
proc `<` *(x, y: Rational): bool =
|
||||
x.toFloat < y.toFloat
|
||||
|
||||
proc `<=` *(x, y: Rational): bool =
|
||||
x.toFloat <= y.toFloat
|
||||
|
||||
proc abs*(x: Rational): Rational =
|
||||
result.num = abs x.num
|
||||
result.den = abs x.den
|
||||
|
||||
for candidate in 2'i64 .. <((2'i64)^19):
|
||||
var sum: Rational = (1'i64, candidate)
|
||||
for factor in 2'i64 .. pow(candidate.float, 0.5).int64:
|
||||
if candidate mod factor == 0:
|
||||
sum += (1'i64, factor) + (1'i64, candidate div factor)
|
||||
if sum.den == 1:
|
||||
echo "Sum of recipr. factors of ",candidate," = ",sum.num," exactly ",
|
||||
if sum.num == 1: "perfect!" else: ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue