Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
55
Task/Modular-inverse/ObjectIcon/modular-inverse.oi
Normal file
55
Task/Modular-inverse/ObjectIcon/modular-inverse.oi
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# -*- ObjectIcon -*-
|
||||
|
||||
import exception
|
||||
import io
|
||||
|
||||
procedure main ()
|
||||
test_euclid_div ()
|
||||
io.write (inverse (42, 2017))
|
||||
end
|
||||
|
||||
procedure inverse (a, n) # FAILS if there is no inverse.
|
||||
local t, newt, r, newr, quotient, tmp
|
||||
|
||||
if n <= 0 then throw ("non-positive modulus")
|
||||
t := 0; newt := 1
|
||||
r := n; newr := a
|
||||
while newr ~= 0 do
|
||||
{
|
||||
quotient := euclid_div (r, newr)
|
||||
tmp := newt; newt := t - (quotient * newt); t := tmp
|
||||
tmp := newr; newr := r - (quotient * newr); r := tmp
|
||||
}
|
||||
r <= 1 | fail
|
||||
return (if t < 0 then t + n else t)
|
||||
end
|
||||
|
||||
procedure euclid_div (x, y)
|
||||
# This kind of integer division always gives a remainder between 0
|
||||
# and abs(y)-1, inclusive. Thus the remainder is always a LEAST
|
||||
# RESIDUE modulo abs(y). (If y is a positive modulus, then only the
|
||||
# floor division branch is used.)
|
||||
return \
|
||||
if 0 <= y then # Do floor division.
|
||||
(if 0 <= x then x / y
|
||||
else if (-x) % y = 0 then -((-x) / y)
|
||||
else -((-x) / y) - 1)
|
||||
else # Do ceiling division.
|
||||
(if 0 <= x then -(x / (-y))
|
||||
else if (-x) % (-y) = 0 then ((-x) / (-y))
|
||||
else ((-x) / (-y)) + 1)
|
||||
end
|
||||
|
||||
procedure test_euclid_div ()
|
||||
local x, y, q, r
|
||||
|
||||
every x := -100 to 100 do
|
||||
every y := -100 to 100 & y ~= 0 do
|
||||
{
|
||||
q := euclid_div (x, y)
|
||||
r := x - (q * y)
|
||||
if r < 0 | abs (y) <= r then
|
||||
# A remainder was outside the expected range.
|
||||
throw ("Test of euclid_div failed.")
|
||||
}
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue