Skip to content

Instantly share code, notes, and snippets.

@b-adams
Created November 17, 2011 21:28
Show Gist options
  • Save b-adams/1374589 to your computer and use it in GitHub Desktop.
Save b-adams/1374589 to your computer and use it in GitHub Desktop.
Mergesort and three sort orders in Erlang, and pattern matching example
-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).
-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