Skip to content

Instantly share code, notes, and snippets.

@matpalm
Created May 1, 2009 13:05
Show Gist options
  • Save matpalm/105030 to your computer and use it in GitHub Desktop.
Save matpalm/105030 to your computer and use it in GitHub Desktop.
-module(median).
-export([from_file/1,from_list/1]).
from_file(File) ->
io:format("~w\n",[from_list(parse_file:to_list(File))]),
init:stop().
from_list(List) ->
nth_order_stat(round(length(List)/2), List).
nth_order_stat(Target_order_stat, List) ->
Min = lists:min(List),
Max = lists:max(List),
if
(Min == Max) or (Target_order_stat == 1) ->
Min;
Target_order_stat == length(List) ->
Max;
true ->
partition_on_pivot(Target_order_stat, List)
end.
partition_on_pivot(Target_order_stat, List) ->
Pivot = hd(List),
Lt_pivot_predicate = fun(X) -> X < Pivot end,
Num_less_than = count_times_predicate_true(Lt_pivot_predicate, List),
Pivot_order_stat = Num_less_than + 1,
if
Pivot_order_stat == Target_order_stat ->
Pivot;
Pivot_order_stat == 1 ->
nth_order_stat(Target_order_stat, rotate(List));
Pivot_order_stat < Target_order_stat ->
Lt = [ X || X <- List, X >=Pivot ],
Rotated = rotate(Lt),
Adjusted_target_order_stat = Target_order_stat - Num_less_than,
nth_order_stat(Adjusted_target_order_stat, Rotated);
true -> % Pivot_order_stat > Target_order_stat
Gt = [ X || X <- List, X < Pivot ],
nth_order_stat(Target_order_stat, Gt)
end.
count_times_predicate_true(Predicate, List) ->
lists:foldl(fun(X,Acc) ->
case Predicate(X) of
true ->
Acc+1;
false ->
Acc
end
end,
0, List).
rotate([H|T]) ->
T ++ [H].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment