Skip to content

Commit 8e94907

Browse files
committed
Added solution to find build order given projects and dependencies
1 parent 9d93377 commit 8e94907

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.eprogrammerz.examples.algorithm.graphs;
2+
3+
import org.junit.Test;
4+
5+
import java.util.*;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
/**
10+
* You are given a list of projects and a list of dependencies (which is a list of pairs of projects,
11+
* where the second project is dependent on the first project).
12+
* All of a project's dependencies must be built before the project is.
13+
* Find a build order that will allow the projects to be built. If there is no valid build order, return an error.
14+
* EXAMPLE
15+
* Input:
16+
* projects: a, b, c, d, e, f
17+
* dependencies: (a, d), (f, b), (b, d), (f, a), (d, c) Output: f, e, a, b, d, c
18+
*/
19+
public class BuildOrder {
20+
List<Integer> findBuildOrder(List<Integer> projects, List<Pair> dependencies) {
21+
Map<Integer, Set<Integer>> projectToDependencies = new HashMap<>();
22+
23+
// initialize project to empty set
24+
for (int project : projects) {
25+
projectToDependencies.put(project, new HashSet<>());
26+
}
27+
28+
// set project to dependencies
29+
for (Pair pair : dependencies) {
30+
Set<Integer> dep = projectToDependencies.get(pair.y);
31+
dep.add(pair.x);
32+
}
33+
34+
// adj list representation of dependencies
35+
// System.out.println(projectToDependencies); // {1=[6], 2=[6], 3=[4], 4=[1, 2], 5=[], 6=[]}
36+
// build order storing variable
37+
List<Integer> buildOrder = new ArrayList<>();
38+
39+
// to track the completed ones
40+
Queue<Integer> toBeBuilt = new LinkedList<>();
41+
projectToDependencies.forEach((p, d) -> {
42+
if (d.isEmpty()) {
43+
toBeBuilt.add(p);
44+
}
45+
});
46+
47+
while (!toBeBuilt.isEmpty()) {
48+
int ready = toBeBuilt.poll();
49+
buildOrder.add(ready);
50+
51+
// scan this to each dependencies
52+
// if found, remove that
53+
// after removal, if empty
54+
// add that to queue
55+
56+
projectToDependencies.forEach((p, d) -> {
57+
if (d.remove(ready) && d.isEmpty()) {
58+
toBeBuilt.add(p);
59+
}
60+
});
61+
}
62+
63+
return buildOrder;
64+
}
65+
66+
class Pair {
67+
int x;
68+
int y;
69+
70+
Pair(int x, int y) {
71+
this.x = x;
72+
this.y = y;
73+
}
74+
}
75+
76+
@Test
77+
public void testFindBuildOrder() {
78+
79+
List<Integer> projects = Arrays.asList(1, 2, 3, 4, 5, 6);
80+
List<Pair> deps = Arrays.asList(new Pair(1, 4), new Pair(2, 4), new Pair(6, 2), new Pair(6, 1), new Pair(4, 3));
81+
List<Integer> buildOrder = findBuildOrder(projects, deps);
82+
List<Integer> expected = Arrays.asList(5, 6, 1, 2, 4, 3);
83+
assertEquals(expected, buildOrder);
84+
}
85+
}

0 commit comments

Comments
 (0)