%% $Id: ary3.mercury,v 1.1 2001/05/31 02:27:48 doug Exp $
%% http://www.bagley.org/~doug/shootout/
%% based on some code from Ralph Becket

:- module mytest.

:- interface.

:- import_module io.



:- pred main(io__state, io__state).
:- mode main(di, uo) is det.



:- implementation.



:- import_module array, int, list, string, require.



main -->
    io__command_line_arguments(ArgV),
    (   { ArgV = [],        N = 1 }
    ;   { ArgV = [Arg],     N = string__det_to_int(Arg) }
    ;   { ArgV = [_,_|_],   error("usage: arrayaccess [N]") }
    ),
    { X = some_naturals(0, array__init(N, 0)) },
    { Y = add_arrays_n(1000, N-1, X, array__init(N, 0)) },
    io__write_int(array__lookup(Y, 0)),
    io__write_string(" "),
    io__write_int(array__lookup(Y, N - 1)),
    io__nl.



:- func some_naturals(int, array(int)) = array(int).
:- mode some_naturals(in, array_di) = array_uo is det.

some_naturals(I, A) =
    ( if I =< array__max(A) then some_naturals(I + 1, array__set(A, I, I + 1))
                            else A ).



:- func add_array(int, array(int), array(int)) = array(int).
:- mode add_array(in, array_ui, array_di) = array_uo is det.

add_array(I, A, B) =
    ( if I < 0
      then B
      else add_array(I - 1, A, array__set(B, I, array__lookup(A, I) + array__lookup(B, I)))
    ).



:- func add_arrays_n(int, int, array(int), array(int)) = array(int).
:- mode add_arrays_n(in, in, array_ui, array_di) = array_uo is det.

add_arrays_n(N, Len, A, B) =
    ( if N > 0
      then add_arrays_n(N - 1, Len, A, add_array(Len, A, B))
      else B
    ).