qsort([]) -> [];
qsort([H|T]) ->
{Bigger,Smaller} = lists:partition(fun(N) -> N > H end, T),
qsort(Smaller) ++ [H] ++ qsort(Bigger).
Reveal More
qsort([]) -> [];
qsort([H|T]) ->
{Bigger,Smaller} = lists:partition(fun(N) -> N > H end, T),
qsort(Smaller) ++ [H] ++ qsort(Bigger).
Language: Erlang
qsort([]) -> [];
qsort([H|T]) ->
Smaller = [N || N <- T, N =< H],
Bigger = [N || N <- T, N > H],
qsort(Smaller) ++ [H] ++ qsort(Bigger).
Language: Erlang
-module(mapreduce).
-export([reduce_task/2, map_task/2,
test_reduce_task/0, test_map_reduce/0,
repeat_exec/2]).
%%% Execute the function N times,
%%% and put the result into a list
repeat_exec(N,Func) ->
lists:map(Func, lists:seq(0, N-1)).
%%% Identify the reducer process by
%%% using the hashcode of the key
find_reducer(Processes, Key) ->
Index = erlang:phash(Key, length(Processes)),
lists:nth(Index, Processes).
%%% Identify the mapper process by random
find_mapper(Processes) ->
case random:uniform(length(Processes)) of
0 ->
find_mapper(Processes);
N ->
lists:nth(N, Processes)
end.
%%% Collect result synchronously from
%%% a reducer process
collect(Reduce_proc) ->
Reduce_proc ! {collect, self()},
receive
{result, Result} ->
Result
end.
%%% The entry point of the map/reduce framework
map_reduce(M, R, Map_func,
Reduce_func, Acc0, List) ->
%% Start all the reducer processes
Reduce_processes =
repeat_exec(R,
fun(_) ->
spawn(mapreduce, reduce_task,
[Acc0, Reduce_func])
end),
io:format("Reduce processes ~w are started~n",
[Reduce_processes]),
%% Start all mapper processes
Map_processes =
repeat_exec(M,
fun(_) ->
spawn(mapreduce, map_task,
[Reduce_processes, Map_func])
end),
io:format("Map processes ~w are started~n",
[Map_processes]),
%% Send the data to the mapper processes
Extract_func =
fun(N) ->
Extracted_line = lists:nth(N+1, List),
Map_proc = find_mapper(Map_processes),
io:format("Send ~w to map process ~w~n",
[Extracted_line, Map_proc]),
Map_proc ! {map, Extracted_line}
end,
repeat_exec(length(List), Extract_func),
timer:sleep(2000),
%% Collect the result from all reducer processes
io:format("Collect all data from reduce processes~n"),
All_results =
repeat_exec(length(Reduce_processes),
fun(N) ->
collect(lists:nth(N+1, Reduce_processes))
end),
lists:flatten(All_results).
%%% The mapper process
map_task(Reduce_processes, MapFun) ->
receive
{map, Data} ->
IntermediateResults = MapFun(Data),
io:format("Map function produce: ~w~n",
[IntermediateResults ]),
lists:foreach(
fun({K, V}) ->
Reducer_proc =
find_reducer(Reduce_processes, K),
Reducer_proc ! {reduce, {K, V}}
end, IntermediateResults),
map_task(Reduce_processes, MapFun)
end.
%%% The reducer process
reduce_task(Acc0, ReduceFun) ->
receive
{reduce, {K, V}} ->
Acc = case get(K) of
undefined ->
Acc0;
Current_acc ->
Current_acc
end,
put(K, ReduceFun(V, Acc)),
reduce_task(Acc0, ReduceFun);
{collect, PPid} ->
PPid ! {result, get()},
reduce_task(Acc0, ReduceFun)
end.
%%% Testing of Map reduce using word count
test_map_reduce() ->
M_func = fun(Line) ->
lists:map(
fun(Word) ->
{Word, 1}
end, Line)
end,
R_func = fun(V1, Acc) ->
Acc + V1
end,
map_reduce(3, 5, M_func, R_func, 0,
[[this, is, a, boy],
[this, is, a, girl],
[this, is, lovely, boy]]).
Language: Erlang
-module(conway).
-export([mochiweb_request/1, start/1, handle_request/2]).
start(PortString) ->
%{Port, _} = string:to_integer(PortString),
Port = 3001,
mochiweb_http:start([{port, Port}, {loop, {?MODULE, mochiweb_request}}]), receive stop -> stop end.
% http://www.trapexit.org/String_join_with
string_join(Items, Sep) -> lists:flatten(lists:reverse(string_join1(Items, Sep, []))).
string_join1([Head | []], _Sep, Acc) -> [Head | Acc];
string_join1([Head | Tail], Sep, Acc) -> string_join1(Tail, Sep, [Sep, Head | Acc]).
random_matrix(XSize, YSize) ->
array:from_list([random:uniform(2)-1 || _ <- lists:seq(1, XSize*YSize)]).
neighbor_count(CellPos, Matrix, SX, SY) ->
X = CellPos rem SX,
Y = erlang:trunc(CellPos/SX),
% http://ejohn.org/apps/processing.js/examples/topics/conway.html
lists:sum(
[
array:get((X + 1) rem SX + (Y)*SX, Matrix),
array:get((X) + ((Y + 1) rem SY)*SX, Matrix),
array:get((X + SX - 1) rem SX + (Y)*SX, Matrix),
array:get((X) + ((Y + SY - 1) rem SY)*SX, Matrix),
array:get((X + 1) rem SX + ((Y + 1) rem SY)*SX, Matrix),
array:get((X + SX - 1) rem SX + ((Y + 1) rem SY)*SX, Matrix),
array:get((X + SX - 1) rem SX + ((Y + SY - 1) rem SY)*SX, Matrix),
array:get((X + 1) rem SX + ((Y + SY - 1) rem SY)*SX, Matrix)
]).
cell_status(2, S) -> S;
cell_status(3, _) -> 1;
cell_status(_, _) -> 0.
next_cell(CellPos, CellState, Matrix, SX, SY) ->
Neighbors = neighbor_count(CellPos, Matrix, SX, SY),
cell_status(Neighbors, CellState).
next_iteration(Matrix, SX, SY) ->
array:map(fun (N, Z) -> next_cell(N, Z, Matrix, SX, SY) end, Matrix).
state_to_symbol(0) -> " ";
state_to_symbol(1) -> "#";
state_to_symbol(2) -> " \n";
state_to_symbol(3) -> "#\n".
handle_request(Req, Path) ->
SX = 80, % size x of conway grid
SY = 40, % size y of conway grid
case Path of
"/_reset" ->
Matrix = random_matrix(SX, SY),
put(matrix, Matrix),
Req:ok({"text/plain", "Reset OK."});
_ ->
OldMatrix = get(matrix),
Matrix = case OldMatrix of
undefined ->
random_matrix(SX, SY);
_ ->
next_iteration(OldMatrix, SX, SY)
end,
put(matrix, Matrix),
% print newlines when we're at a right-edge
PrettyGrid = array:to_list(array:map(
fun (N, Cell) when N rem SX == 0, N =/= 0 -> state_to_symbol(Cell+2);
(N, Cell) -> state_to_symbol(Cell) end, Matrix)
),
Req:ok({"text/plain", PrettyGrid ++ "\n"})
end.
mochiweb_request(Req) ->
{Path, _, _} = mochiweb_util:urlsplit_path(Req:get(raw_path)),
handle_request(Req, Path).
Language: Erlang
-module(ring).
-export([benchmark/2]).
%% run benchmark for N processes and M messages.
benchmark(N, M) ->
Pids = makering(N),
for(1, M, fun() -> spawn(fun() -> start(message, Pids) end) end).
%% setting up the process ring for sending
%% messages & return the Pids array
makering(M) ->
%% create the processes
Pids = for(1, M, fun() -> spawn(fun() -> loop() end) end),
[Head | _T] = Pids,
%% now setup the ring. one simple init loop to make each
%% each process aware of its next process in the ring
%% we need to pass Head head here as we want to connect
%% the last process back to the head.
connect(Head, Pids),
%% return the Pids
Pids.
%% If only two elements are left in the list just point
%% the first process to the next process. And point the
%% the last process to the first process.
connect(Head, [H, N]) ->
H ! {next, N},
N ! {next, Head};
%% Connect the head and the next element and move to the
%% next elements
connect(Head, [H, N | T]) ->
H ! {next, N},
connect(Head, [N | T]).
%% send message from the beggining of the
%% ring.
start(Mesg, Pids) ->
[Head|T] = Pids,
Head ! {lists:last(T), Mesg, length(Pids)}.
%% order a mass suicide for all process nodes
killall(Pids) ->
lists:foreach(fun(Pid) -> Pid ! die end, Pids).
%% message waiting loop. waits for message and sends
%% it to the next process node. commits sepukku if
%% it is ordered to die.
loop() ->
receive
%% now that we have the next pid, we move into the
%% the listening loop for that function. remember
%% the loop/1 will share the same Pid as this, so
%% no worries.
{next, NextPid} ->
io:format("Set next for ~p as ~p~n", [self(), NextPid]),
wait(NextPid)
end.
wait(NextPid) ->
receive
{From, Mesg, NumHops} when NumHops >= 0 ->
io:format("~w from ~p to ~p~n", [Mesg, From, self()]),
NextPid ! {self(), Mesg, NumHops - 1},
wait(NextPid);
die -> void
end.
%% custom for loops
for(N,N,F) -> [F()];
for(M,N,F) -> [F()|for(M + 1, N, F)].
Language: Erlang
-module(web_server).
-behaviour(gen_server).
-define(SERVER, ?MODULE).
-define(OK, <<"ok">>).
%% API
-export([start_link/1, dispatch_requests/1, stop/0]).
%% gen_server callbacks
%% (Same old, same old. You can skip down to the handle/2 function...)
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
start_link(Port) ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).
init([Port]) ->
mochiweb_http:start(
[{port, Port},
{loop, fun(Req) -> dispatch_requests(Req) end}]),
erlang:monitor(process, mochiweb_http),
{ok, []}.
stop() ->
gen_server:cast(?SERVER, stop).
dispatch_requests(Req) ->
Path = Req:get(path),
Action = clean_path(Path),
handle(Action, Req).
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(stop, State) ->
{stop, normal, State};
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info({'DOWN', _, _, {mochiweb_http, _}, _}, State) ->
{stop, normal, State};
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
mochiweb_http:stop(),
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% This was ripped off from the following blog:
%% http://willcodeforfoo.com/2009/07/29/using-mochiweb-to-create-a-webframework-in-erlang/
handle(Path, Req) ->
CleanPath = clean_path(Path),
CAtom = erlang:list_to_atom(top_level_request(CleanPath)),
ControllerPath = parse_controller_path(CleanPath),
case CAtom of
home ->
IndexContents = case file:read_file("www/index.html") of
{ok, Contents} ->
Contents;
_ ->
"<html><head><title>Error</title></head><body><h1>Uh oh</h1></body></html>"
end,
Req:ok({"text/html", IndexContents});
assets ->
Req:ok(assets:get(ControllerPath));
ControllerAtom ->
Body = case Req:get(method) of
'GET' -> ControllerAtom:get(ControllerPath);
'POST' -> ControllerAtom:post(ControllerPath, decode_data_from_request(Req));
'PUT' -> ControllerAtom:put(ControllerPath, decode_data_from_request(Req));
'DELETE' -> ControllerAtom:delete(ControllerPath, decode_data_from_request(Req));
Other -> subst("Other ~p on: ~s~n", [users, Other])
end,
Req:ok({"text/html", Body})
end.
%% Helper methods:
%% Parse the request body as JSON
decode_data_from_request(Req) ->
RecvBody = Req:recv_body(),
Data = case RecvBody of
<<>> ->
erlang:list_to_binary("{}");
Bin ->
Bin
end,
{struct, Struct} = mochijson2:decode(Data),
Struct.
% Parse the URL path
parse_controller_path(CleanPath) ->
case string:tokens(CleanPath, "/") of
[] ->
[];
[_RootPath|Rest] ->
Rest
end.
%% Strip off the query string off the URL
clean_path(Path) ->
case string:str(Path, "?") of
0 ->
Path;
N ->
string:substr(Path, 1, string:len(Path) - (N+1))
end.
top_level_request(Path) ->
case string:tokens(Path, "/") of
[CleanPath|_Others] ->
CleanPath;
[] ->
"home"
end.
%% Damn, Erlang, I forgot my periods...
-module(flowcoder).
-compile(export_all).
read_post() ->
io:format("Thanks! We missed you!").
%% from my MacBook Pro
-module(flowcoder)
-compile(export_all)
read_post() ->
io:format("Thanks! We missed you!").
%% from my MacBook Pro
Language: Erlang
-module(flowcoder)
-compile(export_all)
read_post() ->
io:format("Looks great, guys!").
%% from my iPhone