[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]
All Source For erlang
Ackermann's Function
```%%% -*- mode: erlang -*-
%%% \$Id: ackermann.erlang,v 1.6 2000/10/07 08:41:43 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(ackermann).
-export([main/1]).

main() -> main(['1']).
main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
io:fwrite("Ack(3,~w): ~w\n", [Num, ack(3, Num)]),
halt(0).

ack(0, N) -> N+1;
ack(M, 0) -> ack(M-1, 1);
ack(M, N) -> ack(M-1, ack(M, N-1)).
```
Array Access
```%%% -*- mode: erlang -*-
%%% \$Id: ary3.erlang,v 1.3 2001/06/18 18:39:33 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/
%%% from James Hague

-module(ary3).
-export([main/1]).

main() -> main(['1']).
main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
ets:new(y, [set, private, named_table]),
clear_y_array(Num),
X = list_to_tuple(lists:seq(1, Num)),
repeat(X, Num, 1000),
[{_,First}] = ets:lookup(y, 1),
[{_,Last}]  = ets:lookup(y, Num),
io:fwrite("~w ~w~n", [First, Last]),
ets:delete(y),
halt(0).

clear_y_array(0) -> ok;
clear_y_array(I) ->
ets:insert(y, {I,0}),
clear_y_array(I - 1).

repeat(X, N, 0) -> ok;
repeat(X, N, K) ->
calc(X, N),
repeat(X, N, K - 1).

calc(X, 0) -> ok;
calc(X, N) ->
ets:update_counter(y, N, element(N, X)),
calc(X, N - 1).
```
Count Lines/Words/Chars
```%%% -*- mode: erlang -*-
%%% \$Id: wc.erlang,v 1.5 2001/06/26 05:09:25 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

% TBD - this program should not assume lines are less than 10000 characters long

main() -> main(['1']).
main(Args) ->
Port = open_port({fd, 0, 1}, [eof, {line, 10000}]),
wc(Port, 0, 0, 0),
halt(0).

wc(Port, NL, NW, NC) ->
{Port, {_, {_, Line}}} ->
wc(Port, NL + 1, NW + cw(Line, out, 0), NC + length(Line) + 1);
{Port, eof} ->
io:format("~w ~w ~w~n", [NL, NW, NC])
end.

% count words in a line (list)
cw([],        _, Count) -> Count;
cw([\$\ |T],   _, Count) -> cw(T, out, Count);
cw([\$\t|T],   _, Count) -> cw(T, out, Count);
cw([_|T],   out, Count) -> cw(T, in, 1 + Count);
cw([_|T],    in, Count) -> cw(T, in, Count).
```
Echo Client/Server
```%%% -*- mode: erlang -*-
%%% \$Id: echo.erlang,v 1.6 2001/06/09 00:02:04 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/
%%% with help from Sebastian Strollo

%%% TBD - need to add check for valid response.

-module(echo).
-export([main/0, main/1, client/2, server/1]).

-define(DATA, <<"Hello there sailor\n">>).

main() -> main(['1']).
main([Arg]) ->
N = list_to_integer(atom_to_list(Arg)),
ServerSock = create_server_sock(),
spawn(?MODULE, client, [N, socket_port(ServerSock)]),
server(ServerSock),
init:stop().

create_server_sock() ->
{ok, LSock} = gen_tcp:listen(0, [binary]),
LSock.

socket_port(Sock) ->
{ok, Port} = inet:port(Sock),
Port.

client(N, ServerPort) ->
{ok, Sock} = gen_tcp:connect("localhost", ServerPort, [binary]),
client_loop(N, Sock),
gen_tcp:close(Sock).

client_loop(0, Sock) -> ok;
client_loop(N, Sock) ->
ok = gen_tcp:send(Sock, ?DATA),
{tcp, Sock, _} -> client_loop(N-1, Sock);
{tcp_closed, Sock} -> ok
end.

server(LSock) ->
{ok, Sock} = gen_tcp:accept(LSock),
server_loop(Sock, 0),
gen_tcp:close(LSock).

server_loop(Sock, Bytes) ->
{tcp, Sock, Packet} ->
ok = gen_tcp:send(Sock, Packet),
server_loop(Sock, Bytes + size(Packet));
{tcp_closed, Sock} ->
io:format("server processed ~w bytes~n", [Bytes]),
gen_tcp:close(Sock)
end.
```
Exception Mechanisms
```%% Used destructive assignment in the process dictionary
%% to keep count of handled exceptions.
%%
%% Usage: start from command line with
%%     erlc exceptions.erl
%%     erl -noinput -s exceptions main 200000

-module(except).
-export([main/1]).

blowup(N) when N rem 2 == 0 -> throw({lo_exception, N});
blowup(N) -> throw({hi_exception, N}).

lo_fun(N) ->
case catch blowup(N) of
{lo_exception, N1} -> put(lo_count, get(lo_count) + 1);
{hi_exception, N2} -> throw({hi_exception, N2})
end.

hi_fun(N) ->
case catch lo_fun(N) of
{hi_exception, N1} -> put(hi_count, get(hi_count) + 1);
_ -> true
end.

some_fun(N) when N > 0 ->
case catch hi_fun(N) of
{lo_exception, N1} -> io:fwrite("~s~n", ["lo_exception should not get here."]);
{hi_exception, N2} -> io:fwrite("~s~n", ["hi_exception should not get here."]);
_ -> true
end,
some_fun(N - 1);
some_fun(0) -> true.

main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
put(hi_count, 0),
put(lo_count, 0),
some_fun(Num),
io:fwrite("~s~w ~s~w~n", ["Exceptions: HI=", get(hi_count),"/ LO=", get(lo_count)]),
halt(0).

```
Fibonacci Numbers
```%%% -*- mode: erlang -*-
%%% \$Id: fibo.erlang,v 1.2 2000/12/24 19:10:50 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(fibo).
-export([main/1]).

main() -> main(['1']).
main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
io:fwrite("~w\n", [fib(Num)]),
halt(0).

fib(N) when N < 2 -> 1;
fib(N) -> fib(N-2) + fib(N-1).
```
Hash (Associative Array) Access
```%%% -*- 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.

```
Hashes, Part II
```%%% -*- mode: erlang -*-
%%% \$Id: hash2.erlang,v 1.1 2001/05/21 02:22:57 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

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

main() -> main(['1']).
main([Arg]) ->
N = list_to_integer(atom_to_list(Arg)),
H1 = ets:new(one, [set]),
H2 = ets:new(two, [set]),
doinserts1(0, H1),
doinserts2(N, H1, H2),
io:format("~w ~w ~w ~w~n", [value(H1, list_to_atom("foo_1")),
value(H1, list_to_atom("foo_9999")),
value(H2, list_to_atom("foo_1")),
value(H2, list_to_atom("foo_9999"))]),
halt(0).

doinserts1(10000, _) -> ok;
doinserts1(I, H) ->
Key = list_to_atom(lists:append("foo_", integer_to_list(I))),
ets:insert(H, { Key, I }),
doinserts1(I+1, H).

doinserts2(0, _, _) -> ok;
doinserts2(I, H1, H2) ->
doinserts2(I-1, H1, H2).

Key = ets:first(H1),

value(Tab, Key) -> { _, V } = hd(ets:lookup(Tab, Key)), V.

Val1 = value(H1, Key),
case (catch ets:update_counter(H2, Key, Val1)) of
{'EXIT', {badarg, _}} -> ets:insert(H2, {Key, Val1});
_                     -> true
end,

```
Heapsort
```%% \$Id: heapsort.erlang,v 1.0 2002/09/24 12:16:00 dada Exp \$
%%
%% contributed by Isaac Gouy
%%
%% Quick and Dirty transliteration from the Mercury solution
%% with +1 adjustment for array indexes.
%% Mercury uses 0..N-1 and Erlang uses 1..N
%%
%% Usage: start from command line with
%%     erlc heapsort.erl
%%     erl -noinput -s heapsort main 10000

-module(heapsort).
-export([main/1]).

random_heap(I, Seed, H) ->
if
I < size(H) ->
{NextSeed, R} = gen_random(Seed),
random_heap(I+1, NextSeed, up_heap(I, R, H));
true -> H
end.

up_heap(N, Y, H) ->
HalfN = N div 2,
X = element(HalfN+1, H), %%%% +1
Condition = 0 < N andalso X < Y,
if
Condition -> up_heap(HalfN, Y, setelement(N+1, H, X)); %%%% +1
true -> setelement(N+1, H, Y) %%%% +1
end.

heapsort(0, H) -> H;
heapsort(N, H) -> heapsort(N-1, remove_greatest(N, H)).

remove_greatest(N, H) ->
X = element(0+1, H), %%%% +1
Y = element(N+1, H), %%%% +1
down_heap(0, N-1, Y, setelement(N+1, H, X)). %%%% +1

down_heap(I, N, X, H) ->
L = I + I + 1,
R = L + 1,
if
N < L ->
setelement(I+1, H, X); %%%% +1
true ->
Condition = R < N andalso element(R+1, H) > element(L+1, H), %%%% +1
J = if
Condition -> R;
true -> L
end,
Y = element(J+1, H),
if
X > Y -> setelement(I+1, H, X); %%%% +1
true -> down_heap(J, N, X, setelement(I+1, H, Y)) %%%% +1
end
end.

gen_random(Seed) ->
IM = 139968, IA = 3877, IC = 29573,
S = ((Seed * IA) + IC) rem IM,
{S, S/IM}.

main([Arg]) ->
N = list_to_integer(atom_to_list(Arg)),
Seed = 42,
RandomHeap = random_heap(0, Seed, erlang:make_tuple(N, 0.0)),
SortedHeap = heapsort(N-1, RandomHeap),
io:fwrite("~.10f~n", [element(N, SortedHeap)]),
halt(0).

```
Hello World
```%%% -*- mode: erlang -*-
%%% \$Id: hello.erlang,v 1.1 2001/06/17 22:00:34 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(hello).
-export([main/0]).

main() -> io:fwrite("hello world\n", []), halt(0).
```
Matrix Multiplication
```%% Doesn't check matrix sizes match but
%% not restricted to square matrices.
%%
%% Represent matrix as tuple of tuples.
%% Doesn't use destructive assignment so building a
%% matrix creates an awful lot of temporary lists.
%%
%% Usage: start from command line with
%%     erlc multiply.erl
%%     erl -noinput -s multiply main 1

-module(matrix).
-export([main/1]).
-import(lists, [reverse/1]).

sumprod(0, _, _, Sum, _, _) -> Sum;
sumprod(I, C, R, Sum, M1, M2) ->
NewSum = Sum + (element(I,element(R,M1)) * element(C,element(I,M2))),
sumprod(I-1, C, R, NewSum, M1, M2).

rowmult(_, 0, _, L, _, _) -> list_to_tuple(L);
rowmult(I, C, R, L, M1, M2) ->
SumProd = sumprod(I, C, R, 0, M1, M2),
rowmult(I, C-1, R, [SumProd|L], M1, M2).

mmult(_, _, 0, MM, _, _) -> list_to_tuple(MM);
mmult(I, C, R, MM, M1, M2) ->
NewRow = rowmult(I, C, R, [], M1, M2),
mmult(I, C, R-1, [NewRow|MM], M1, M2).

mmult(M1, M2) ->
Inner = size(M2), % could optimize more by hardcoding the sizes
NRows = size(M1),
mmult(Inner, NRows, NRows,[], M1, M2).

repeatmmult(1, M1, M2) -> mmult(M1, M2);
repeatmmult(NTimes, M1, M2) ->
mmult(M1, M2),
repeatmmult(NTimes-1, M1, M2).

mkrow(0, L, Count) -> {list_to_tuple(reverse(L)), Count};
mkrow(N, L, Count) -> mkrow(N-1, [Count|L], Count+1).

mkmatrix(0, _, _, M) -> list_to_tuple(reverse(M));
mkmatrix(NR, NC, Count, M) ->
{Row, NewCount} = mkrow(NC, [], Count),
mkmatrix(NR-1, NC, NewCount, [Row|M]).

mkmatrix(NR, NC) -> mkmatrix(NR, NC, 1, []).

main([Arg]) ->
NTimes = list_to_integer(atom_to_list(Arg)),
Size = 30,
M1 = mkmatrix(Size, Size),
M2 = mkmatrix(Size, Size),
MM = repeatmmult(NTimes, M1, M2),
Val1 = element(1,element(1, MM)),
Val2 = element(4,element(3, MM)), % get col 4 out of row 3
Val3 = element(3,element(4, MM)), % get col 3 out of row 4
Val4 = element(5,element(5, MM)),
io:fwrite("~w ~w ~w ~w~n", [Val1, Val2, Val3, Val4]),
halt(0).

```
Nested Loops
```%%% -*- mode: erlang -*-
%%% \$Id: nestedloop.erlang,v 1.1 2001/05/15 07:00:27 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(nestedloop).
-export([main/1]).

main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
io:fwrite("~w\n", [loopA(Num, Num, 0)]),
halt(0).

loopA(0, M, N) -> N;
loopA(I, M, N) -> loopA(I - 1, M, loopB(M, M, N)).

loopB(0, M, N) -> N;
loopB(I, M, N) -> loopB(I - 1, M, loopC(M, M, N)).

loopC(0, M, N) -> N;
loopC(I, M, N) -> loopC(I - 1, M, loopD(M, M, N)).

loopD(0, M, N) -> N;
loopD(I, M, N) -> loopD(I - 1, M, loopE(M, M, N)).

loopE(0, M, N) -> N;
loopE(I, M, N) -> loopE(I - 1, M, loopF(M, N)).

loopF(0, N) -> N;
loopF(I, N) -> loopF(I - 1, 1 + N).
```
```%%% \$Id: prodcons.erlang,v 1.0 2002/10/21 16:58:00 dada Exp \$
%%%
%%% contributed by James Hague

-module(prodcons).
-export([main/0, main/1, producer/2, consumer/1]).

main() -> main(['1']).
main([Arg]) ->
N = list_to_integer(atom_to_list(Arg)),
spawn(prodcons, producer, [self(), N]),
{Produced, Consumed} ->
io:fwrite("~w ~w~n", [Produced, Consumed]),
halt(0)
end.

producer(From, N) ->
Result = producer_loop(spawn(prodcons, consumer, [0]), 0, N),
From ! Result.

producer_loop(Consumer, Produced, 0) ->
Consumer ! {self(), stop},
Consumed -> {Produced, Consumed}
end;
producer_loop(Consumer, Produced, N) ->
Consumer ! {self(), N},
ok -> producer_loop(Consumer, Produced + 1, N - 1)
end.

consumer(Consumed) ->
{From, stop} ->
From ! Consumed;
{From, I} ->
From ! ok,
consumer(Consumed + 1)
end.

```
Random Number Generator
```%%% -*- mode: erlang -*-
%%% \$Id: random.erlang,v 1.3 2001/05/18 07:39:45 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(random).
-export([main/1]).

main() -> main(['1']).
main([Arg]) ->
N = list_to_integer(atom_to_list(Arg)),
io:fwrite("~.9f\n", [rand(N, 42, 0.0, 100.0)]),
halt(0).

-define(IM, 139968).
-define(IA, 3877).
-define(IC, 29573).

rand(0, _, Rand, _) -> Rand;
rand(N, Seed, Rand, Max) ->
NewSeed = (Seed * ?IA + ?IC) rem ?IM,
NewRand = Max * NewSeed / ?IM,
rand(N-1, NewSeed, NewRand, Max).
```
Regular Expression Matching
```%%% -*- mode: erlang -*-
%%% \$Id: regexmatch.erlang,v 1.7 2001/01/06 22:35:23 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

%% get the program argument, which is how many test iterations to run
main() -> main(['1']).
main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
{ok, Re} = regexp:parse(
"(^|[^0-9\\(])"        % preceeding non-digit or bol
"("                % area code
"\\([0-9][0-9][0-9]\\)"    % is either 3 digits in parens
"|"                % or
"[0-9][0-9][0-9]"        % just 3 digits
")"                % end of area code
" "                % area code is followed by one space
"[0-9][0-9][0-9]"        % exchange is 3 digits
"[ -]"                % separator is either space or dash
"[0-9][0-9][0-9][0-9]"        % last 4 digits
"(\$|[^0-9])"            % must be followed by a non-digit
),
test(Num, Re, Plist),
halt(0).

test(1, Regexp, Plist) ->
% display output on last iteration
Nums = match_phones(Regexp, Plist),
print_phones(1, Nums),
true;
test(N, Regexp, Plist) ->
match_phones(Regexp, Plist),
test(N-1, Regexp, Plist).

print_phones(Count, [H|T]) ->
[A,E,N] = H,
% A,E,N is a list of the matching sub-expressions, which are:
% Areacode (3 digits), Exchange (3 digits), Number (4 digits)
io:fwrite("~w: (~s) ~s-~s~n", [Count, A,E,N]),
print_phones(Count+1, T);
print_phones(_, []) ->
true.

match_phones(Regexp, List) ->
mapfilter(
fun(String) ->
case regexp:matches(String, Regexp) of
{match, []}      -> false;
{match, Matches} -> parse_phone(String, Matches);
_                -> false
end
end,
List).

parse_phone(Str, [H|T]) ->
{Start, Len} = H,
% Numstr is something that looks like a complete phone #
Numstr = string:substr(Str, Start, Len),
case regexp:matches(Numstr, "[0-9][0-9][0-9][0-9]*") of
{match, []}      -> false;
{match, Matches} ->
lists:map(fun({Offset, Length}) ->
string:substr(Numstr, Offset, Length) end,
Matches);
_                -> false
end;
parse_phone(Str, []) -> [].

mapfilter(Fun, [H|T]) ->
case Fun(H) of
false -> mapfilter(Fun, T);
New   -> [New | mapfilter(Fun, T)]
end;
mapfilter(_, []) -> [].

Port = open_port({fd, 0, 1}, [eof, {line, 512}]),

{Port, eof} ->
lists:reverse(Lines);
{Port, {_, {_, Line}}} ->
end.
```
Reverse a File
```%%% -*- mode: erlang -*-
%%% \$Id: reversefile.erlang,v 1.1 2001/05/15 08:05:58 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

main() -> main(['1']).
main(Args) ->
init(),
halt(0).

init() ->
Port = open_port({fd, 1, 0}, [eof, {line, 128}]),
printlist(rev(Port, [])).

rev(Port, Lines) ->
{Port, {_, {_, Line}}} ->
rev(Port, [Line|Lines]);
{Port, eof} ->
Lines
end.

printlist([])     -> [];
printlist([H|T])  -> io:format("~s~n", [H]), printlist(T).
```
Sieve of Erathostenes
```%%% -*- mode: erlang -*-
%%% \$Id: sieve.erlang,v 1.12 2000/10/07 08:41:44 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(sieve).
-export([main/0, main/1]).
-import(io, [fwrite/2]).
-import(lists, [seq/2]).
-import(math, [sqrt/1]).

%% get the program argument, which is how many test iterations
%% to run
main() -> main(['1']).
main(Arg) ->
[Tmp] = Arg,
Num = list_to_integer(atom_to_list(Tmp)),
test(Num),
halt(0).

test(N) ->
Primes = primes(8192),
Count = length(Primes),
case N > 1 of
true  -> test(N-1);
false -> fwrite("Count: ~w\n", [Count])
end.

primes(Size) ->
era(sqrt(Size), seq(2,Size)).

%% modified from Maurice Castro's original (below), sped it up
%% a fraction by reordering clauses and args, but if it's less
%% clear now, that's my fault.
%% -Doug

era(Max, [H|T]) when H =< Max ->
[H | era(Max, sieve([H|T], H))];
era(Max, L) ->
L.

sieve([H|T], N) when H rem N =/= 0 ->
[H | sieve(T, N)];
sieve([H|T], N) ->
sieve(T, N);
sieve([], N) ->
[].

%%% eratosthenes algorithm from Maurice Castro, with permission,
%%% from his book, _Erlang in Real Time_, ISBN: 0864447434
%%% http://www.serc.rmit.edu.au/~maurice/erlbk/eg/choice/erasto.erl
%
%era(Max, L) when hd(L) =< Max ->
%    Prime = hd(L),
%    [Prime | era(Max, sieve(Prime, L))];
%era(Max, L) ->
%    L.
%
%sieve(N, []) ->
%    [];
%sieve(N, [H|T]) when H rem N == 0 ->
%    sieve(N, T);
%sieve(N, [H|T]) ->
%    [H | sieve(N, T)].
```
Spell Checker
```%%% -*- mode: erlang -*-
%%% \$Id: spellcheck.erlang,v 1.1 2001/05/26 05:05:04 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

main() -> main(['1']).
main(Args) ->
% load dictionary into hash table (erlang ets table)
% read words from stin and print those not in dictionary
spell(Dict),
halt(0).

Dict = ets:new(i_am_a_carrot, [set]),
{ok, In} = file:open("Usr.Dict.Words", [raw]),
% I'm just guessing that the file opened above has fd=3
% this is a total hack, but I could find nothing in the Erlang
% documention on how to do this.
Port = open_port({fd, 3, 1}, [eof, {line, 64}]),
file:close(In),
Dict.

Dict = ets:new(i_am_a_carrot, [set]),
%Port = open_port({fd, ????, 1}, [eof, {line, 64}]),
Port = open_port({spawn, "cat Usr.Dict.Words"}, [eof, {line, 64}]),
%file:close(In),
Dict.

{Port, {_, {_, Word}}} ->
Atom = list_to_atom(Word),
ets:insert(Dict, { Atom, 1 }),
{Port, eof} -> ok
end.

spell(Dict) ->
Port = open_port({fd, 0, 1}, [eof, {line, 64}]),
spell(Port, Dict).

spell(Port, Dict) ->
{Port, {_, {_, Word}}} ->
Atom = list_to_atom(Word),
case ets:lookup(Dict, Atom) of
[] -> io:format("~w~n",[Atom]);
_  -> ok
end,
spell(Port, Dict);
{Port, eof} -> ok
end.
```
Statistical Moments
```%% \$Id: moments.erl,v 1.0 2002/09/24 12:09:00 dada Exp \$
%%
%% Code contributed by Isaac Gouy
%%
%% Usage: start from command line with
%%     erlc moments.erl
%%     erl -noinput -s moments main 200000

-module(moments).
-export([main/0]).
-import(lists, [sort/1, foldl/3, nth/2]).

accumulate([], Mean, Ad, Av, As, Ak) ->
accumulate([H|T], Mean, Ad, Av, As, Ak) ->
D = H - Mean,
D2 = D * D,
accumulate(T, Mean, Ad + abs(D), Av + D2, As + (D2 * D), Ak + (D2 * D2)).

median(L, N) -> medianS(sort(L), N).

medianS(L, N) ->
Mid = N div 2,
case N rem 2 of
0 -> (nth(Mid, L) + nth(Mid + 1, L)) / 2;
1 -> nth(Mid, L)
end.

skew(N, As, V, SD) when V > 0.0 -> As / (N * V * SD);
skew(N, As, V, SD) -> 0.

kurtosis(N, Ak, V) when V > 0.0 -> Ak / (N * V * V) - 3;
kurtosis(N, Ak, V) -> 0.

stats(L) ->
N = length(L),
io:fwrite("~s~w~n", ["n:                  ", N]),
io:fwrite("~s~f~n", ["median:             ", median(L, N)]),

Mean = foldl(fun(X, Sum) -> X + Sum end, 0.0, L) / N,
io:fwrite("~s~f~n", ["mean:               ", Mean]),

{Ad, Av, As, Ak} = accumulate(L, Mean, 0.0, 0.0, 0.0, 0.0),
io:fwrite("~s~f~n", ["average_deviation:  ", Ad / N]),

Variance = Av / (N - 1),
Standard_deviation = math:sqrt(Variance),
io:fwrite("~s~f~n", ["standard_deviation: ", Standard_deviation]),
io:fwrite("~s~f~n", ["variance:           ", Variance]),
io:fwrite("~s~f~n", ["skew:               ", skew(N, As, Variance, Standard_deviation)]),
io:fwrite("~s~f~n", ["kurtosis:           ", kurtosis(N, Ak, Variance)]),
io:fwrite("~n ", []).

main() ->
stats(lists:seq(1,500,1)),
halt(0).

```
String Concatenation
```%%% -*- mode: erlang -*-
%%% \$Id: strcat.erlang,v 1.1 2001/05/15 07:37:04 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

-module(strcat).
-export([main/1]).

main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
io:fwrite("~w\n", [length(string:copies("hello\n", Num))]),
halt(0).
```
Sum a Column of Integers
```%%% -*- mode: erlang -*-
%%% \$Id: sumcol.erlang,v 1.2 2000/12/31 18:56:43 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

main() -> main(['1']).
main(Args) ->
io:put_chars( sumcol( io:fread( '', "~d" ), 0) ),
halt(0).

sumcol( eof, Sum ) ->
io_lib:format( "~w~n", [Sum] );
sumcol( {ok, [N]}, Sum ) ->
io:put_chars( io_lib:format( "~w~n", [Sum] ) ),
sumcol( io:fread( '', "~d" ), Sum + N ).
```
Word Frequency Count
```%%% -*- mode: erlang -*-
%%% \$Id: wordfreq.erlang,v 1.8 2000/12/31 22:54:17 doug Exp \$
%%% http://www.bagley.org/~doug/shootout/

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

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

%% ignore program argument
main() -> main(['1']).
main(Args) ->
OutL = fun ({Word, Count}) ->
io:format("~7w\t~s~n", [Count, Word])
end,
lists:foreach(OutL, sortedfreqs()),
halt(0).

% sort the results, descending
sortedfreqs() ->
Port = open_port({fd, 0, 1}, [eof, {line, 512}]),
WordCountList = count_words_from_stream(ets:new(freqtab, [ordered_set]), Port),
lists:reverse(lists:keysort(2, WordCountList)).

count_words_from_stream(Table, Port) ->
{Port, eof} ->
ets:delete(Table, ''),
ets:tab2list(Table);
{Port, {_, {_, Line}}} ->
count_words([], Line, Table),
count_words_from_stream(Table, Port)
end.

count_word(Word, Table) ->
WordAtom = list_to_atom(Word),
case (catch ets:update_counter(Table, WordAtom, 1)) of
ets:insert(Table, {WordAtom, 1});
_ ->
true
end.

% count_words(Word_Accumulator, Line_of_Chars, Table)
count_words([], [], Table) -> true;
count_words(Word, [], Table) ->
count_word(Word, Table);
count_words(Word, [H|T], Table) when H >= \$a, H=< \$z ->
NewWord = lists:append(Word, [H]),
count_words(NewWord, T, Table);
count_words(Word, [H|T], Table) when H >= \$A, H=< \$Z ->
NewWord = lists:append(Word, [(H - \$A) + \$a]),
count_words(NewWord, T, Table);
% we hit a non-word character so count previous word and continue
count_words(Word, [H|T], Table) ->
count_word(Word, Table),
count_words([], T, Table).
```