Skip to content

Instantly share code, notes, and snippets.

@andreburgaud
Last active June 28, 2017 05:17
Show Gist options
  • Save andreburgaud/620cfbe8d5c678e484fa9935a0a9a7ca to your computer and use it in GitHub Desktop.
Save andreburgaud/620cfbe8d5c678e484fa9935a0a9a7ca to your computer and use it in GitHub Desktop.
FutureLearn - Functional Programming in Erlang 2.9 - Constructing lists with recursive functions
-module(transform).
-export([double/1,evens/1,median/1,modes/1,sort/1,counters/2]).
%% ----------------------------------------------------------------------------
%% Double
double([]) -> [];
double([X|Xs]) -> [2*X | double(Xs)].
%% ----------------------------------------------------------------------------
%% Evens
evens([]) -> [];
evens([X|Xs]) when X rem 2 == 0 -> [X | evens(Xs)];
evens([_|Xs]) -> evens(Xs).
%% ----------------------------------------------------------------------------
%% Median
%% Naive recursive implementation of a filter to support sort
filterL(_,[]) -> [];
filterL(Pivot, [X|Xs]) when X < Pivot -> [X|filterL(Pivot,Xs)];
filterL(Pivot, [_|Xs]) -> filterL(Pivot,Xs).
filterP(_,[]) -> [];
filterP(Pivot, [X|Xs]) when X >= Pivot -> [X|filterP(Pivot,Xs)];
filterP(Pivot, [_|Xs]) -> filterP(Pivot,Xs).
%% Naive recursive implementation of qsort using filters filterL and filterP
sort([]) -> [];
sort([Pivot|Xs]) ->
sort(filterL(Pivot,Xs)) ++ [Pivot] ++ sort(filterP(Pivot,Xs)).
median([X]) -> X;
median(Xs) ->
S = sort(Xs),
L = length(Xs),
case L rem 2 of
0 ->
(lists:nth(L div 2, S) + lists:nth((L div 2) + 1, S)) / 2;
_ ->
lists:nth((L div 2) + 1, S)
end.
%% ----------------------------------------------------------------------------
%% Modes
%% Helper to add element to a counters list.
add(X, []) -> [{X,1}];
add(X, [{Y,C}|Counters]) when X == Y -> [{X, C+1}|Counters];
add(X, [{Y,C}|Counters]) -> [{Y, C}|add(X, Counters)].
%% Helper to create a counters list. An element of a counter is a tuple {N, C}
%% where N is a number and C its associated counter.
counters([],Counters) -> Counters;
counters([X|Xs],Counters) ->
counters(Xs,add(X,Counters)).
%% Helper to filter the list of numbers with the maximum counter from a list of
%% counters.
filter_max(_,[],Modes) -> Modes;
filter_max(Max,[{X,C}|Counters],Modes) when C == Max ->
filter_max(Max, Counters,[X|Modes]);
filter_max(Max,[{X,C}|Counters],_) when C > Max ->
filter_max(C, Counters,[X]);
filter_max(Max,[_|Counters],Modes) ->
filter_max(Max, Counters, Modes).
%% Main modes function. Returns a sorted list of numbers with the maximum
%% occurence in a given list of numbers.
modes([]) -> [];
modes(Xs) ->
Counters = counters(Xs,[]),
sort(filter_max(0, Counters, [])).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment