%% $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))).