Last active
June 28, 2017 05:17
-
-
Save andreburgaud/620cfbe8d5c678e484fa9935a0a9a7ca to your computer and use it in GitHub Desktop.
FutureLearn - Functional Programming in Erlang 2.9 - Constructing lists with recursive functions
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(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