%%% -*- mode: erlang -*-
%%% $Id: hash.erlang,v 1.3 2001/05/21 01:28:48 doug Exp $
%%% http://www.bagley.org/~doug/shootout/
%%% Tweaked by James Hague.

%% Use ETS tables (Erlang's associative store).

-module(hash).
-export([main/0, main/1]).

main() -> main(['1']).
main([Arg]) ->
    N = list_to_integer(atom_to_list(Arg)),
    H = ets:new(ok, [set]),
    doinserts(0, N, H),
    Count = dolookups(N, 0, H),
    io:format("~w~n", [Count]),
    halt(0).

format_hex(0) -> $0;
format_hex(X) -> format_hex(X, []).
format_hex(0, Hex) -> Hex;
format_hex(X, Hex) ->
    N = X band 16#f,
    if
       N < 10 -> format_hex(X bsr 4, [N+$0 | Hex]);
       true ->   format_hex(X bsr 4, [N+($a-10) | Hex])
    end.

doinserts(N, N, H) -> ok;
doinserts(I, N, H) ->
    Hx = format_hex(I),
    ets:insert(H, {Hx, I}),
    doinserts(I+1, N, H).

dolookups(0, C, H) -> C;
dolookups(I, C, H) ->
    Nx = integer_to_list(I),
    case ets:lookup(H, Nx) of
        []-> dolookups(I-1, C, H);
        _ -> dolookups(I-1, C+1, H)
    end.