Created
June 27, 2017 21:47
-
-
Save i7an/25be51593a759f311dec759343e80631 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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