%% $Id: hash.mercury,v 1.1 2001/07/28 19:11:22 doug Exp $
%% http://www.bagley.org/~doug/shootout/
%% from Fergus Henderson

:- module mytest.
:- interface.
:- import_module io.

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

:- implementation.
:- import_module string, hash_table, list, int.

main -->
    io__command_line_arguments(Args),
    { N = (if Args = [Arg], to_int(Arg, N0) then N0 else 1) },
    { X = insert_values(1, N, hash_table__new(string_double_hash, 18, 0.33)) },
    print(count(N, X, 0)), nl.

:- func insert_values(int, int, hash_table(string, int)) = hash_table(string, int).
:- mode insert_values(in, in, hash_table_di) = hash_table_uo.
insert_values(I, N, X0) =
    (if I > N then X0
    else insert_values(I + 1, N, X0^elem(int_to_base_string(I, 16)) := I)).

:- func count(int, hash_table(string, int), int) = int.
:- mode count(in, hash_table_ui, in) = out.
count(I, X, C0) =
    (if I = 0 then C0
    else count(I - 1, X,
        (if search(X, int_to_string(I), _) then C0 + 1 else C0))).