Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
75
Task/Modular-inverse/Oberon-2/modular-inverse.oberon
Normal file
75
Task/Modular-inverse/Oberon-2/modular-inverse.oberon
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
(*-*- mode: indented-text; tab-width: 2; -*-*)
|
||||
|
||||
MODULE modularInverseInOberon2;
|
||||
|
||||
IMPORT Out;
|
||||
|
||||
(* Division with a non-negative remainder. This will work no matter
|
||||
how your compiler handles DIV (and mine seems not to do what the
|
||||
Oberon-2 specification says). *)
|
||||
PROCEDURE euclidDiv (x, y : INTEGER) : INTEGER;
|
||||
VAR q : INTEGER;
|
||||
BEGIN
|
||||
IF 0 <= y THEN (* Do floor division. *)
|
||||
IF 0 <= x THEN
|
||||
q := x DIV y
|
||||
ELSE
|
||||
q := -((-x) DIV y);
|
||||
IF (-x) MOD y # 0 THEN q := q - 1 END
|
||||
END;
|
||||
ELSE (* Do ceiling division. *)
|
||||
IF 0 <= x THEN
|
||||
q := -(x DIV (-y))
|
||||
ELSE
|
||||
q := ((-x) DIV (-y));
|
||||
IF (-x) MOD (-y) # 0 THEN q := q + 1 END
|
||||
END
|
||||
END;
|
||||
RETURN q
|
||||
END euclidDiv;
|
||||
|
||||
(* I have added this unit test because, earlier, I posted a buggy
|
||||
version of euclidDiv. *)
|
||||
PROCEDURE testEuclidDiv;
|
||||
VAR x, y, q, r : INTEGER;
|
||||
BEGIN
|
||||
FOR x := -100 TO 100 DO
|
||||
FOR y := -100 TO 100 DO
|
||||
IF y # 0 THEN
|
||||
q := euclidDiv (x, y);
|
||||
r := x - (q * y);
|
||||
IF (r < 0) OR (ABS (y) <= r) THEN
|
||||
(* A remainder was outside the expected range. *)
|
||||
Out.String ("euclidDiv fails its test")
|
||||
END
|
||||
END
|
||||
END
|
||||
END
|
||||
END testEuclidDiv;
|
||||
|
||||
PROCEDURE inverse (a, n : INTEGER) : INTEGER;
|
||||
VAR t, newt : INTEGER;
|
||||
VAR r, newr : INTEGER;
|
||||
VAR quotient : INTEGER;
|
||||
VAR tmp : INTEGER;
|
||||
BEGIN
|
||||
t := 0; newt := 1;
|
||||
r := n; newr := a;
|
||||
WHILE newr # 0 DO
|
||||
quotient := euclidDiv (r, newr);
|
||||
tmp := newt; newt := t - (quotient * newt); t := tmp;
|
||||
tmp := newr; newr := r - (quotient * newr); r := tmp
|
||||
END;
|
||||
IF r > 1 THEN
|
||||
t := -1
|
||||
ELSIF t < 0 THEN
|
||||
t := t + n
|
||||
END;
|
||||
RETURN t
|
||||
END inverse;
|
||||
|
||||
BEGIN
|
||||
testEuclidDiv;
|
||||
Out.Int (inverse (42, 2017), 0);
|
||||
Out.Ln
|
||||
END modularInverseInOberon2.
|
||||
Loading…
Add table
Add a link
Reference in a new issue