Jump to content

Modular arithmetic: Difference between revisions

Line 1,420:
{{out}}
{1}<sub>13</sub>
 
=={{header|Mercury}}==
{{works with|Mercury|22.01.1}}
 
Numbers have to be converted to <code>ordinary(Number)</code> or <code>modular(Number, Modulus)</code> before they are plugged into <code>f</code>. The two kinds can be mixed: if any operation involves a "modular" number, then the result will be "modular", but otherwise the result will be "ordinary".
 
(There are limitations in Mercury's current system of overloads that make it more difficult than I care to deal with, to do this so that <code>f</code> could be invoked directly on the <code>integer</code> type.)
 
<syntaxhighlight lang="mercury">
%% -*- mode: mercury; prolog-indent-width: 2; -*-
 
:- module modular_arithmetic_task.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module exception.
:- import_module integer.
 
:- type modular_integer
---> modular(integer, integer)
; ordinary(integer).
 
:- func operate((func(integer, integer) = integer),
modular_integer, modular_integer) = modular_integer.
operate(OP, modular(A, M1), modular(B, M2)) = C :-
if (M1 = M2)
then (C = modular(mod(OP(A, B), M1), M1))
else throw("mismatched moduli").
operate(OP, modular(A, M), ordinary(B)) = C :-
C = modular(mod(OP(A, B), M), M).
operate(OP, ordinary(A), modular(B, M)) = C :-
C = modular(mod(OP(A, B), M), M).
operate(OP, ordinary(A), ordinary(B)) = C :-
C = ordinary(OP(A, B)).
 
:- func '+'(modular_integer, modular_integer) = modular_integer.
(A : modular_integer) + (B : modular_integer) = operate(+, A, B).
 
:- func pow(modular_integer, modular_integer) = modular_integer.
pow(A : modular_integer, B : modular_integer) = operate(pow, A, B).
 
:- pred display(modular_integer::in, io::di, io::uo) is det.
display(X, !IO) :-
if (X = modular(A, _)) then print(A, !IO)
else if (X = ordinary(A)) then print(A, !IO)
else true.
 
:- func f(modular_integer) = modular_integer.
f(X) = Y :-
Y = pow(X, ordinary(integer(100))) + X
+ ordinary(integer(1)).
 
main(!IO) :-
X1 = ordinary(integer(10)),
X2 = modular(integer(10), integer(13)),
print("No modulus: ", !IO),
display(f(X1), !IO),
nl(!IO),
print("modulus 13: ", !IO),
display(f(X2), !IO),
nl(!IO).
 
:- end_module modular_arithmetic_task.
</syntaxhighlight>
 
{{out}}
<pre>$ mmc --use-subdirs --make modular_arithmetic_task && ./modular_arithmetic_task
Making Mercury/int3s/modular_arithmetic_task.int3
Making Mercury/ints/modular_arithmetic_task.int
Making Mercury/cs/modular_arithmetic_task.c
Making Mercury/os/modular_arithmetic_task.o
Making modular_arithmetic_task
No modulus: 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
modulus 13: 1
</pre>
 
=={{header|Nim}}==
1,448

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.