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) ->
receive
{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),
receive
{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) ->
receive
{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) ->
addTables(H1, H2),
doinserts2(I-1, H1, H2).
addTables(H1, H2) ->
Key = ets:first(H1),
addTables(Key, H1, H2).
value(Tab, Key) -> { _, V } = hd(ets:lookup(Tab, Key)), V.
addTables('$end_of_table', _, _) -> ok;
addTables(Key, H1, H2) ->
Val1 = value(H1, Key),
case (catch ets:update_counter(H2, Key, Val1)) of
{'EXIT', {badarg, _}} -> ets:insert(H2, {Key, Val1});
_ -> true
end,
addTables(ets:next(H1, Key), H1, H2).
|
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).
|
Producer/Consumer Threads |
%%% $Id: prodcons.erlang,v 1.0 2002/10/21 16:58:00 dada Exp $
%%% http://dada.perl.it/shootout
%%%
%%% 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]),
receive
{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},
receive
Consumed -> {Produced, Consumed}
end;
producer_loop(Consumer, Produced, N) ->
Consumer ! {self(), N},
receive
ok -> producer_loop(Consumer, Produced + 1, N - 1)
end.
consumer(Consumed) ->
receive
{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
),
Plist = readlines(),
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(_, []) -> [].
readlines() ->
Port = open_port({fd, 0, 1}, [eof, {line, 512}]),
readlines_from_stream([], Port).
readlines_from_stream(Lines, Port) ->
receive
{Port, eof} ->
lists:reverse(Lines);
{Port, {_, {_, Line}}} ->
readlines_from_stream([Line|Lines], Port)
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) ->
receive
{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)
Dict = load_dict(),
% read words from stin and print those not in dictionary
spell(Dict),
halt(0).
load_dict() ->
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}]),
read_dict(Port, Dict),
file:close(In),
Dict.
load_dict_1() ->
Dict = ets:new(i_am_a_carrot, [set]),
%{ok, In} = file:open("Usr.Dict.Words", [read]),
%Port = open_port({fd, ????, 1}, [eof, {line, 64}]),
Port = open_port({spawn, "cat Usr.Dict.Words"}, [eof, {line, 64}]),
read_dict(Port, Dict),
%file:close(In),
Dict.
read_dict(Port, Dict) ->
receive
{Port, {_, {_, Word}}} ->
Atom = list_to_atom(Word),
ets:insert(Dict, { Atom, 1 }),
read_dict(Port, Dict);
{Port, eof} -> ok
end.
spell(Dict) ->
Port = open_port({fd, 0, 1}, [eof, {line, 64}]),
spell(Port, Dict).
spell(Port, Dict) ->
receive
{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) ->
{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) ->
receive
{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
{'EXIT', {badarg, _}} ->
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).
|