Created
November 17, 2011 21:28
-
-
Save b-adams/1374589 to your computer and use it in GitHub Desktop.
Mergesort and three sort orders in Erlang, and pattern matching example
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(cs228records). | |
-export([listJobbers/2]). | |
listJobbers(NameOfJob, [CurrentRecord | RemainingRecords]) -> | |
case CurrentRecord of | |
{person, {name, UsefulName}, {job, NameOfJob}, _} -> | |
[ UsefulName | listJobbers(NameOfJob, RemainingRecords)] | |
; | |
{person, {name, UselessName}, {job, RandomJob}, {Label, Data}} -> | |
io:format("Ignoring the <~p-~p'ed> ~p, who is a ~p.~n", [Data, Label, UselessName, RandomJob]), | |
listJobbers(NameOfJob, RemainingRecords) | |
; | |
ImpersonalGarbage -> | |
io:format("Ignoring non-person data ~p.~n", [ImpersonalGarbage]), | |
listJobbers(NameOfJob, RemainingRecords) | |
end | |
; | |
listJobbers(_NameOfJob, []) -> []. | |
%Record1 = {person, {name, "Joe"}, {job, "Woodshop Teacher"}, {fingers, 7}}. | |
%Record2 = {vehicle, {name, "Herbie"}, {type, "Bug"}}. | |
%Record3 = {person, {name, "Curly"}, {job, "Stooge"}, {fingers, 10}}. | |
%Record4 = {vehicle, {name, "Thomas"}, {type, "Train Engine"}}. | |
%Record5 = {person, {name, "Larry"}, {job, "Stooge"}, {fingers, 10}}. | |
%AllRecords = [Record1, Record2, Record3, Record4, Record5]. | |
%c(records). | |
%records:listJobbers("Woodshop Teacher", AlLRecords). | |
%records:listJobbers("Stooge", AlLRecords). | |
%records:listJobbers("Astronaut", AlLRecords). |
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(cs228sort). | |
-export([fishMergesort/1, normalMergesort/1, mergesort/2, factors/1, factorMergesort/1]). | |
splitlist(List) -> splitlist(List, {[], []}). | |
splitlist([], {Left, Right}) -> {Left, Right}; | |
splitlist([X], {Left, Right}) -> {[X|Left], Right}; | |
splitlist([L,R|T], {Left, Right}) -> splitlist(T, {[L|Left], [R|Right]}). | |
%For testing, add splitlist/1 to export list | |
%cs228sort:splitlist([1,2,3,4,5,6,7,8]). | |
zipup({[], []}, _NeedSwap) -> []; | |
zipup({NonEmpty, []}, _NeedSwap) -> NonEmpty; | |
zipup({[], NonEmpty}, _NeedSwap) -> NonEmpty; | |
zipup({[L|Left], [R|Right]}, NeedSwap) -> | |
case {NeedSwap(L,R), NeedSwap(R,L)} of | |
{true, false} -> [R | zipup({[L|Left], Right}, NeedSwap)] ; | |
{false, true} -> [L | zipup({Left, [R|Right]}, NeedSwap)] ; | |
{false, false} -> [L, R|zipup({Left, Right}, NeedSwap)] ; | |
X -> io:format("WTF, '~p' and '~p' are incomparable!? (~p)~n", [L, R, X]),[] | |
end. | |
%For testing, add zipup/1 to export list | |
%cs228sort:zipup([1,4,5,8], [2,3,4,6], fun(Lo, Hi) -> Lo > Hi end). | |
mergesort([], _ListOrder) -> []; | |
mergesort([X], _ListOrder) -> [X]; | |
mergesort(Data, ListOrder) -> | |
{OneHalf, OtherHalf} = splitlist(Data), | |
SortedHalves = {mergesort(OneHalf, ListOrder), mergesort(OtherHalf, ListOrder)}, | |
zipup(SortedHalves, ListOrder). | |
%For testing | |
%cs228sort:mergesort([3,1,4,1,5,9,2,6,5,3,5,7]). | |
normalMergesort(List) -> mergesort(List, fun defaultOutOfOrderFunction/2). | |
fishMergesort(List) -> mergesort(List, fun fishOutOfOrder/2). | |
factorMergesort(List) -> mergesort(List, fun factorOrder/2). | |
defaultOutOfOrderFunction(Lo, Hi) -> Lo > Hi. | |
fishOutOfOrder(Lo, Hi) -> | |
Odd = fun(N) -> N rem 2 == 1 end, | |
case {Odd(Lo), Odd(Hi)} of | |
{false, true} -> true; | |
{true, false} -> false; | |
{true, true} -> defaultOutOfOrderFunction(Lo, Hi); | |
{false, false} -> defaultOutOfOrderFunction(Hi, Lo) | |
end. | |
factors(N) -> factors(N, 2, []). | |
factors(N, Test, Found) -> | |
% io:format("Is ~p a factor of ~p? So far I've found ~p~n", [Test, N, Found]), | |
if | |
Test >= N -> [N|Found]; | |
N rem Test == 0 -> factors(N div Test, Test, [Test|Found]); | |
Test == 2 -> factors(N, Test+1, Found); | |
true -> factors(N, Test+2, Found) | |
end. | |
factorOrder(Lo, Hi) -> | |
LoFactors = length(factors(Lo)), | |
HiFactors = length(factors(Hi)), | |
if | |
HiFactors == LoFactors -> defaultOutOfOrderFunction(Hi, Lo); | |
true -> defaultOutOfOrderFunction(LoFactors, HiFactors) | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment