Skip to content

Instantly share code, notes, and snippets.

@i7an
Created June 27, 2017 21:47
Show Gist options
  • Save i7an/25be51593a759f311dec759343e80631 to your computer and use it in GitHub Desktop.
Save i7an/25be51593a759f311dec759343e80631 to your computer and use it in GitHub Desktop.
-module(main).
-export([double/1, evens/1, median/1, frequent/1]).
-import(my_lists, [map/2, filter/2, qsort/2, drop_first/1, drop_last/1]).
double(L) -> map(L, fun (X) -> 2*X end).
evens(L) -> filter(L, fun (X) -> (X rem 2) == 0 end).
% median value for sorted list
median_sorted([A]) -> A;
median_sorted([_,_] = Pair) -> Pair;
median_sorted(SortedList) ->
Trimmed = drop_first(drop_last(SortedList)),
median_sorted(Trimmed).
median(List) ->
SortedList = qsort(List, fun (X,Y) -> X < Y end),
median_sorted(SortedList).
% counts elements in presorted list
% [1,1,1,5,5] -> [{1,3},{5,2}]
count([], Counts) -> Counts;
count([X|Xs], [{X, Count}|Rest]) ->
count(Xs, [{X,Count+1}|Rest]);
count([X|Xs], Counts) ->
count(Xs,[{X,1}|Counts]).
frequent(List) ->
Counts = count(qsort(List, fun (X,Y) -> X < Y end), []),
SortedCounts = qsort(Counts, fun ({_,Cx}, {_,Cy}) -> Cx > Cy end),
case SortedCounts of
[] -> [];
[{X, Cx}|Rest] ->
BigCounts = filter(Rest, fun({_El,C}) -> Cx==C end),
[X|map(BigCounts, fun ({El,_}) -> El end)]
end.
-module(main_test).
-export([test/0]).
-import(main, [double/1, evens/1, median/1, frequent/1]).
test_double() ->
[2,4] = double([1,2]),
[] = double([]).
test_evens() ->
[2,4] = evens([1,2,3,4]),
[] = evens([]).
test_median() ->
2 = median([3,1,2]),
[2,3] = median([4,2,3,1]).
test_frequent() ->
[2,1] = frequent([1,2,3,2,1]),
[3] = frequent([1,2,2,3,3,3]),
[] = frequent([]).
test() ->
test_double(),
test_evens(),
test_median(),
test_frequent(),
ok.
-module(my_lists).
-export([map/2, partition/2, filter/2, qsort/2, drop_first/1, drop_last/1]).
map(L, Fn) -> map(L, Fn, []).
map([], _Fn, Res) -> Res;
map([X|Xs], Fn, Res) -> map(Xs, Fn, Res ++ [Fn(X)]).
% splits list L by the predicate Fn
partition(L, Fn) -> partition(L, Fn, [], []).
partition([], _Fn, Left, Right) -> {Left, Right};
partition([X|Xs], Fn, Left, Right) ->
case Fn(X) of
true -> partition(Xs, Fn, Left ++ [X], Right);
_false -> partition(Xs, Fn, Left, Right ++ [X])
end.
filter(L, Fn) ->
{Left, _} = partition(L, Fn),
Left.
% FnGt/2 returns true if second argument > first argument
qsort([], _FnGt) -> [];
qsort([X|Xs], FnGt) ->
{Left, Right} = partition(Xs, fun (El) -> FnGt(El,X) end),
qsort(Left,FnGt) ++ [X] ++ qsort(Right,FnGt).
drop_last(List) -> drop_last(List, []).
drop_last([_A], List) -> List;
drop_last([A|As], List) -> drop_last(As, List ++ [A]).
drop_first([_A|As]) -> As.
-module(my_lists_test).
-export([test/0]).
-import(my_lists, [map/2, partition/2, filter/2, qsort/2, drop_first/1, drop_last/1]).
test_map() ->
Double = fun (X) -> X+X end,
[2,4,6] = map([1,2,3], Double),
[] = map([], Double).
test_partition() ->
Predicate = fun (X) -> X < 5 end,
{[1,3], [5,6]} = partition([1,5,3,6], Predicate),
{[], []} = partition([], Predicate).
test_filter() ->
Predicate = fun (X) -> X < 5 end,
[1,2,3] = filter([1,2,6,3], Predicate),
[] = filter([], Predicate).
test_qsort() ->
Asc = fun (X,Y) -> X < Y end,
Desc = fun (X,Y) -> X > Y end,
[1,2,3] = qsort([3,1,2], Asc),
[3,2,1] = qsort([3,1,2], Desc),
[] = qsort([], Asc).
test_drop_first() ->
[2] = drop_first([1,2]).
test_drop_last() ->
[1] = drop_last([1,2]).
test() ->
test_map(),
test_partition(),
test_filter(),
test_qsort(),
test_drop_first(),
test_drop_last(),
ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment