Skip to content

Instantly share code, notes, and snippets.

@RyanGough
Last active August 29, 2015 14:20
Show Gist options
  • Save RyanGough/165385e4d191430849da to your computer and use it in GitHub Desktop.
Save RyanGough/165385e4d191430849da to your computer and use it in GitHub Desktop.
ordered jobs kata in erlang
-module (jobsort).
-export ([sort/1,test/0]).
sort(JobSpec) ->
EdgesAndVertices = get_edges_and_vertices(string:tokens(JobSpec, "\r\n"), [], []),
Graph = build_graph(EdgesAndVertices),
case digraph_utils:is_acyclic(Graph) of
true ->
lists:reverse(digraph_utils:topsort(Graph));
false ->
"jobs list contains cyclic dependancy"
end.
build_graph({Vertices,Edges}) ->
Graph = digraph:new(),
lists:foldl(fun (V,_) -> digraph:add_vertex(Graph, V) end, [], Vertices),
lists:foldl(fun ({E1,E2},_) -> digraph:add_edge(Graph,E1,E2) end, [], Edges),
Graph.
get_edges_and_vertices([], Vertices, Edges) ->
{lists:usort(Vertices), Edges};
get_edges_and_vertices([Job|OtherJobs], Vertices, Edges) ->
case string:tokens(Job, " ") of
[Dependant, _, Dependancy] ->
get_edges_and_vertices(OtherJobs, [Dependant, Dependancy | Vertices], [{Dependant,Dependancy} | Edges]);
[Vertex,_] ->
get_edges_and_vertices(OtherJobs, [Vertex | Vertices],Edges)
end.
test() ->
%1 no jobs, empty result
[] = sort(""),
%2 single job, no dependancy
["a"] = sort("a ->"),
%3 multiple single jobs, no dependancies
["a","c","b"] = sort("a ->\r\nb ->\r\nc ->"),
%4 single job with dependancies
["b","a"] = sort("a -> b"),
%5 multiple jobs with dependancies
["c","b","a","e","d","f"] = sort("a -> b\r\nb -> c\r\nd -> e\r\nf -> a"),
%6 self dependancy
"jobs list contains cyclic dependancy" = sort("a -> a"),
%6 cyclic dependancy
"jobs list contains cyclic dependancy" = sort("a -> b\r\nb -> c\r\nc -> a"),
%7 multiple dependancies \ dependants
["b","d","c","a","f"] = sort("a -> b\r\na -> c\r\nc -> d\r\nf -> c"),
"tests passed".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment