Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,96 @@
PROGRAM RATIONAL_ARITH
!
! for rosettacode.org
!
TYPE RATIONAL=(NUM,DEN)
DIM SUM:RATIONAL,ONE:RATIONAL,KF:RATIONAL
DIM A:RATIONAL,B:RATIONAL
PROCEDURE ABS(A.->A.)
A.NUM=ABS(A.NUM)
END PROCEDURE
PROCEDURE NEG(A.->A.)
A.NUM=-A.NUM
END PROCEDURE
PROCEDURE ADD(A.,B.->A.)
LOCAL T
T=A.DEN*B.DEN
A.NUM=A.NUM*B.DEN+B.NUM*A.DEN
A.DEN=T
END PROCEDURE
PROCEDURE SUB(A.,B.->A.)
LOCAL T
T=A.DEN*B.DEN
A.NUM=A.NUM*B.DEN-B.NUM*A.DEN
A.DEN=T
END PROCEDURE
PROCEDURE MULT(A.,B.->A.)
A.NUM*=B.NUM A.DEN*=B.DEN
END PROCEDURE
PROCEDURE DIVIDE(A.,B.->A.)
A.NUM*=B.DEN
A.DEN*=B.NUM
END PROCEDURE
PROCEDURE EQ(A.,B.->RES%)
RES%=A.NUM*B.DEN=B.NUM*A.DEN
END PROCEDURE
PROCEDURE LT(A.,B.->RES%)
RES%=A.NUM*B.DEN<B.NUM*A.DEN
END PROCEDURE
PROCEDURE GT(A.,B.->RES%)
RES%=A.NUM*B.DEN>B.NUM*A.DEN
END PROCEDURE
PROCEDURE NE(A.,B.->RES%)
RES%=A.NUM*B.DEN<>B.NUM*A.DEN
END PROCEDURE
PROCEDURE LE(A.,B.->RES%)
RES%=A.NUM*B.DEN<=B.NUM*A.DEN
END PROCEDURE
PROCEDURE GE(A.,B.->RES%)
RES%=A.NUM*B.DEN>=B.NUM*A.DEN
END PROCEDURE
PROCEDURE NORMALIZE(A.->A.)
LOCAL A,B,T
A=A.NUM B=A.DEN
WHILE B<>0 DO
T=A
A=B
B=T-B*INT(T/B)
END WHILE
A.NUM/=A A.DEN/=A
IF A.DEN<0 THEN A.NUM*=-1 A.DEN*=-1 END IF
END PROCEDURE
BEGIN
ONE.NUM=1 ONE.DEN=1
FOR N=2 TO 2^19-1 DO
SUM.NUM=1 SUM.DEN=N
FOR K=2 TO SQR(N) DO
IF N=K*INT(N/K) THEN
KF.NUM=1 KF.DEN=K
ADD(SUM.,KF.->SUM.)
NORMALIZE(SUM.->SUM.)
KF.DEN=INT(N/K)
ADD(SUM.,KF.->SUM.)
NORMALIZE(SUM.->SUM.)
END IF
END FOR
EQ(SUM.,ONE.->RES%)
IF RES% THEN PRINT(N;" is perfect") END IF
END FOR
END PROGRAM

View file

@ -0,0 +1,6 @@
;; Finding perfect numbers
(define (sum/inv n) ;; look for div's in [2..sqrt(n)] and add 1/n
(for/fold (acc (/ n)) [(i (in-range 2 (sqrt n)))]
#:break (> acc 1) ; no hope
(when (zero? (modulo n i ))
(set! acc (+ acc (/ i) (/ i n))))))

View file

@ -0,0 +1,17 @@
;; rational operations
(+ 1/42 1/666) → 59/2331
42/666 → 7/111
(expt 3/4 7) → 2187/16384 ; 3/4 ^7
(/ 6 8) → 3/4 ;; / operator → rational
(// 6 8) → 0.75 ;; // operator → float
(* 6/7 14/12) → 1
;; even perfect numbers (up to 100000)
(for [(i (in-range 4 100000 2))] ;; 8 seconds
(when (= (sum/inv i) 1)
(printf "🍏 🍒 🍓 %d is perfect." i)))
🍏 🍒 🍓 6 is perfect.
🍏 🍒 🍓 28 is perfect.
🍏 🍒 🍓 496 is perfect.
🍏 🍒 🍓 8128 is perfect.

View file

@ -0,0 +1,46 @@
-- parent script "Frac"
property num
property denom
----------------------------------------
-- @constructor
-- @param {integer} numerator
-- @param {integer} [denominator=1]
----------------------------------------
on new (me, numerator, denominator)
if voidP(denominator) then denominator = 1
if denominator=0 then return VOID -- rule out division by zero
g = me._gcd(numerator, denominator)
if g<>0 then
numerator = numerator/g
denominator = denominator/g
else
numerator = 0
denominator = 1
end if
if denominator<0 then
numerator = -numerator
denominator = -denominator
end if
me.num = numerator
me.denom = denominator
return me
end
----------------------------------------
-- Returns string representation "<num>/<denom>"
-- @return {string}
----------------------------------------
on toString (me)
return me.num&"/"&me.denom
end
----------------------------------------
--
----------------------------------------
on _gcd (me, a, b)
if a = 0 then return b
if b = 0 then return a
if a > b then return me._gcd(b, a mod b)
return me._gcd(a, b mod a)
end

View file

@ -0,0 +1,83 @@
-- Frac library (movie script)
----------------------------------------
-- Shortcut for creating 'frac' values
-- @param {integer} numerator
-- @param {integer} denominator
-- @return {instance}
----------------------------------------
on frac (numerator, denominator)
return script("Frac").new(numerator, denominator)
end
----------------------------------------
-- All functions below this comment only support 'fracs', i.e. instances
-- of the Frac Class, as arguments. An integer n is casted to frac via frac(n).
----------------------------------------
-- Optionally supports more than 2 arguments
on fAdd (a, b) -- ...
res = a
repeat with i = 2 to the paramCount
p = param(i)
num = res.num * p.denom + res.denom * p.num
denom = res.denom * p.denom
res = frac(num, denom)
end repeat
return res
end
on fSub (a, b)
return frac(a.num * b.den - a.den * b.num, a.den * b.den)
end
-- Optionally supports more than 2 arguments
on fMul (a, b) -- ...
res = a
repeat with i = 2 to the paramCount
p = param(i)
res = frac(res.num * p.num, res.denom * p.denom)
end repeat
return res
end
on fDiv (a, b)
return frac(a.num * b.denom, a.denom * b.num)
end
on fAbs (f)
return frac(abs(f.num), f.denom)
end
on fNeg (f)
return frac(-f.num, f.denom)
end
on fEQ (a, b)
diff = fSub(a, b)
return diff.num=0
end
on fNE (a, b)
return not fEQ (a, b)
end
on fGT (a, b)
diff = fSub(a, b)
return diff.num>0
end
on fLT (a, b)
diff = fSub(a, b)
return diff.num<0
end
on fGE (a, b)
diff = fSub(a, b)
return diff.num>=0
end
on fLE (a, b)
diff = fSub(a, b)
return diff.num<=0
end

View file

@ -0,0 +1,13 @@
f = frac(2,3)
put f.toString()
-- "2/3"
-- fractions are normalized on the fly
f = frac(4,6)
put f.toString()
-- "2/3"
-- casting integer to frac
f = frac(23)
put f.toString()
-- "23/1"

View file

@ -0,0 +1,15 @@
-- in some movie script
----------------------------------------
-- Prints all perfect numbers up to n
-- @param {integer|float} n
----------------------------------------
on findPerfects (n)
repeat with i = 2 to n
sum = frac(1, i)
cnt = sqrt(i)
repeat with fac = 2 to cnt
if i mod fac = 0 then sum = fAdd(sum, frac(1, fac), frac(fac, i))
end repeat
if sum.denom = sum.num then put i
end repeat
end

View file

@ -0,0 +1,5 @@
findPerfects(power(2, 19))
-- 6
-- 28
-- 496
-- 8128

View 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: ""

View file

@ -0,0 +1,106 @@
without warning -- (several unused routines in this code)
constant NUM = 1, DEN = 2
type frac(object r)
return sequence(r) and integer(r[NUM]) and integer(r[DEN]) and length(r)=2
end type
function normalise(object n, atom d=0)
atom g
if sequence(n) then
{n,d} = n
end if
if d<0 then
n = -n
d = -d
end if
g = gcd(n,d)
return {n/g,d/g}
end function
function frac_new(integer n,d=1)
return normalise(n,d)
end function
function frac_abs(frac r)
return {abs(r[NUM]),r[DEN]}
end function
function frac_inv(frac r)
return reverse(r)
end function
function frac_add(frac a, frac b)
integer {an,ad} = a,
{bn,bd} = b
return normalise(an*bd+bn*ad,ad*bd)
end function
function frac_sub(frac a, frac b)
integer {an,ad} = a,
{bn,bd} = b
return normalise(an*bd-bn*ad,ad*bd)
end function
function frac_mul(frac a, frac b)
integer {an,ad} = a,
{bn,bd} = b
return normalise(an*bn,ad*bd)
end function
function frac_div(frac a, frac b)
integer {an,ad} = a,
{bn,bd} = b
return normalise(an*bd,ad*bn)
end function
function frac_eq(frac a, frac b)
return a==b
end function
function frac_ne(frac a, frac b)
return a!=b
end function
function frac_lt(frac a, frac b)
return frac_sub(a,b)[NUM]<0
end function
function frac_gt(frac a, frac b)
return frac_sub(a,b)[NUM]>0
end function
function frac_le(frac a, frac b)
return frac_sub(a,b)[NUM]<=0
end function
function frac_ge(frac a, frac b)
return frac_sub(a,b)[NUM]>=0
end function
function is_perfect(integer num)
frac sum = frac_new(0)
sequence f = factors(num,1)
for i=1 to length(f) do
sum = frac_add(sum,frac_new(1,f[i]))
end for
return frac_eq(sum,frac_new(2))
end function
procedure get_perfect_numbers()
atom t0 = time()
for i=2 to power(2,19) do
if is_perfect(i) then
printf(1,"perfect: %d\n",i)
end if
end for
printf(1,"elapsed: %3.2f seconds\n",time()-t0)
integer pn5 = power(2,12)*(power(2,13)-1) -- 5th perfect number
if is_perfect(pn5) then
printf(1,"perfect: %d\n",pn5)
end if
end procedure
get_perfect_numbers()