Factors of an integer: Difference between revisions

Content added Content deleted
(→‎{{header|MUMPS}}: Added a Mercury implementation.)
Line 1,319: Line 1,319:
setify(makelist(fac[1]^i, i, 0, fac[2]))),
setify(makelist(fac[1]^i, i, 0, fac[2]))),
ifactors(n))));</lang>
ifactors(n))));</lang>

=={{header|Mercury}}==
Mercury is both a logic language and a functional language. As such there are two possible interfaces for calculating the factors of an integer. This code shows both styles. Note that much of the code here is ceremony put in place to have this be something which can actually compile. The actual factoring is contained in the predicate <code>factor/2</code> and in the function <code>factor/1</code>. The predicate <code>main/2</code> is just the entry point for the program and the predicate <code>main2/3</code> is used to do command line processing so multiple numbers can be factored.

The function form is implemented in terms of the predicate form rather than duplicating all of the predicate code.

This implementation of factoring works as follows:
1. The input number itself and 1 are both considered factors.
2. The numbers between 2 and the square root of the input number are checked for even division.
3. If the incremental number divides evenly into the input number, both the incremental number and the quotient are added to the list of factors.

===fac.m===
<lang Mercury>:- module fac.

:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module float, getopt, int, list, math, string.

:- pred factor(int::in, list(int)::out) is det.
:- pred factor(int::in, int::in, int::in, list(int)::in, list(int)::out) is det.
:- func factor(int::in) = (list(int)::out) is det.

:- pred main2(list(string)::in, io::di, io::uo) is det.

factor(N, L) :-
Limit = float.truncate_to_int(math.sqrt(float(N))),
factor(N, 2, Limit, [1,N], L).
factor(N, X, Z, LC, L) :-
(X > Z ->
L = list.sort(LC)
;
(0 = N mod X ->
factor(N, X + 1, Z, [X, N / X | LC], L)
;
factor(N, X + 1, Z, LC, L)
)
).

factor(N) = L :- factor(N, L).

main(!IO) :-
io.command_line_arguments(Args, !IO),
main2(Args, !IO).

main2([], !IO) :-
io.write_string("Finished.\n", !IO).

main2([Arg|Args], !IO) :-
(string.to_int(Arg, N) ->
factor(N, X),

io.format("factor(%d, [", [i(N)], !IO),
io.write_list(X, ",", io.write_int, !IO),
io.write_string("])\n", !IO),

io.format("factor(%d) = [", [i(N)], !IO),
io.write_list(factor(N), ",", io.write_int, !IO),
io.write_string("]\n", !IO)
;
io.format("Bad argument: %s\n", [s(Arg)], !IO)
),
main2(Args, !IO).</lang>

Use of the code looks like this:

<pre><nowiki>$ mmc fac.m && ./fac 100 999 12345678 booger
factor(100, [1,2,4,5,10,10,20,25,50,100])
factor(100) = [1,2,4,5,10,10,20,25,50,100]
factor(999, [1,3,9,27,37,111,333,999])
factor(999) = [1,3,9,27,37,111,333,999]
factor(12345678, [1,2,3,6,9,18,47,94,141,282,423,846,14593,29186,43779,87558,131337,262674,685871,1371742,2057613,4115226,6172839,12345678])
factor(12345678) = [1,2,3,6,9,18,47,94,141,282,423,846,14593,29186,43779,87558,131337,262674,685871,1371742,2057613,4115226,6172839,12345678]
Bad argument: booger
Finished.</nowiki></pre>


=={{header|MUMPS}}==
=={{header|MUMPS}}==
Line 1,332: Line 1,410:
w $$factors(53) ; [1,53]
w $$factors(53) ; [1,53]
w $$factors(64) ; [1,2,4,8,16,32,64]</lang>
w $$factors(64) ; [1,2,4,8,16,32,64]</lang>



=={{header|Niue}}==
=={{header|Niue}}==