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,24 @@
\ return "extended gcd" of a and b; The result satisfies the equation:
\ a*x + b*y = gcd(a,b)
: n:xgcd \ a b -- gcd x y
dup 0 n:= if
1 swap \ -- a 1 0
else
tuck n:/mod
-rot recurse
tuck 4 roll
n:* n:neg n:+
then ;
\ Return modular inverse of n modulo mod, or null if it doesn't exist (n and mod
\ not coprime):
: n:invmod \ n mod -- invmod
dup >r
n:xgcd rot 1 n:= not if
2drop null
else
drop dup 0 n:< if r@ n:+ then
then
rdrop ;
42 2017 n:invmod . cr bye

View file

@ -0,0 +1,26 @@
PROGRAM MOD_INV
!$INTEGER
PROCEDURE MUL_INV(A,B->T)
LOCAL NT,R,NR,Q,TMP
IF B<0 THEN B=-B
IF A<0 THEN A=B-(-A MOD B)
T=0 NT=1 R=B NR=A MOD B
WHILE NR<>0 DO
Q=R DIV NR
TMP=NT NT=T-Q*NT T=TMP
TMP=NR NR=R-Q*NR R=TMP
END WHILE
IF (R>1) THEN T=-1 EXIT PROCEDURE ! NO INVERSE
IF (T<0) THEN T+=B
END PROCEDURE
BEGIN
MUL_INV(42,2017->T) PRINT(T)
MUL_INV(40,1->T) PRINT(T)
MUL_INV(52,-217->T) PRINT(T) ! pari semantics for negative modulus
MUL_INV(-486,217->T) PRINT(T)
MUL_INV(40,2018->T) PRINT(T)
END PROGRAM

View file

@ -0,0 +1,10 @@
(lib 'math) ;; for egcd = extended gcd
(define (mod-inv x m)
(define-values (g inv q) (egcd x m))
(unless (= 1 g) (error 'not-coprimes (list x m) ))
(if (< inv 0) (+ m inv) inv))
(mod-inv 42 2017) → 1969
(mod-inv 42 666)
🔴 error: not-coprimes (42 666)

View file

@ -0,0 +1,12 @@
import integers.egcd
def modinv( a, m ) =
val (g, x, _) = egcd( a, m )
if g != 1 then error( a + ' and ' + m + ' not coprime' )
val res = x % m
if res < 0 then res + m else res
println( modinv(42, 2017) )

View file

@ -0,0 +1,13 @@
proc mulInv(a0, b0): int =
var (a, b, x0) = (a0, b0, 0)
result = 1
if b == 1: return
while a > 1:
let q = a div b
a = a mod b
swap a, b
result = result - q * x0
swap x0, result
if result < 0: result += b0
echo mulInv(42, 2017)

View file

@ -0,0 +1,22 @@
// euclid ( a b -- u v r )
// Return r = gcd(a, b) and (u, v) / r = au + bv
: euclid(a, b)
| q u u1 v v1 |
b 0 < ifTrue: [ b neg ->b ]
a 0 < ifTrue: [ b a neg b mod - ->a ]
1 dup ->u ->v1
0 dup ->v ->u1
while(b) [
b a b /mod ->q ->b ->a
u1 u u1 q * - ->u1 ->u
v1 v v1 q * - ->v1 ->v
]
u v a ;
: invmod(a, modulus)
a modulus euclid 1 == ifFalse: [ drop drop null return ]
drop dup 0 < ifTrue: [ modulus + ] ;

View file

@ -0,0 +1,18 @@
see "42 %! 2017 = " + multInv(42, 2017) + nl
func multInv a,b
b0 = b
x0 = 0
multInv = 1
if b = 1 return 0 ok
while a > 1
q = floor(a / b)
t = b
b = a % b
a = t
t = x0
x0 = multInv - q * x0
multInv = t
end
if multInv < 0 multInv = multInv + b0 ok
return multInv

View file

@ -0,0 +1 @@
say 42.modinv(2017)

View file

@ -0,0 +1,13 @@
func invmod(a, n) {
var (t, nt, r, nr) = (0, 1, n, a % n)
while (nr != 0) {
var quot = int((r - (r % nr)) / nr);
(nt, t) = (t - quot*nt, nt);
(nr, r) = (r - quot*nr, nr);
}
r > 1 && return()
t < 0 && (t += n)
t
}
say invmod(42, 2017)