diff --git a/.gitignore b/.gitignore index e660fd93d..140a150d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ bin/ +.DS_Store +.gradle/ +gradle/ +Java/gradlew +Java/gradlew.bat diff --git a/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Graph.java b/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Graph.java new file mode 100644 index 000000000..dd9d5e546 --- /dev/null +++ b/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Graph.java @@ -0,0 +1,29 @@ +package Q4_07_Build_Order.BFS; + +import java.util.ArrayList; +import java.util.HashMap; + +public class Graph { + private ArrayList nodes = new ArrayList(); + private HashMap map = new HashMap(); + + public Project getOrCreateNode(String name) { + if (!map.containsKey(name)) { + Project node = new Project(name); + nodes.add(node); + map.put(name, node); + } + + return map.get(name); + } + + public void addEdge(String startName, String endName) { + Project start = getOrCreateNode(startName); + Project end = getOrCreateNode(endName); + start.addNeighbor(end); + } + + public ArrayList getNodes() { + return nodes; + } +} diff --git a/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Project.java b/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Project.java new file mode 100644 index 000000000..40edafc9d --- /dev/null +++ b/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Project.java @@ -0,0 +1,53 @@ +package Q4_07_Build_Order.BFS; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Project { + private List children = new ArrayList(); + + private List parents = new ArrayList(); + + private HashMap map = new HashMap(); + private String name; + + private boolean processed = false; + + public Project(String n) { + name = n; + } + + public String getName() { + return name; + } + + public void addNeighbor(Project node) { + if (!map.containsKey(node.getName())) { + children.add(node); + map.put(node.getName(), node); + node.addParent(this); + } + } + + public List getChildren() { + return children; + } + + public boolean isProcessed() { + return this.processed; + } + + public void setProcessed(boolean processed) { + this.processed = processed; + } + + public List getParents() { + return this.parents; + } + + public void addParent(Project project) { + this.parents.add(project); + } + +} diff --git a/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Question.java b/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Question.java new file mode 100644 index 000000000..75fa9e4b4 --- /dev/null +++ b/Java/Ch 04. Trees and Graphs/Q4_07_Build_Order/BFS/Question.java @@ -0,0 +1,92 @@ +package Q4_07_Build_Order.BFS; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +public class Question { + /* Build the graph, adding the edge (a, b) if b is dependent on a. + * Assumes a pair is listed in “build order”. The pair (a, b) in + * dependencies indicates that b depends on a and a must be built + * before b. */ + public static Graph buildGraph(String[] projects, String[][] dependencies) { + Graph graph = new Graph(); + for (String project : projects) { + graph.getOrCreateNode(project); + } + + for (String[] dependency : dependencies) { + String first = dependency[0]; + String second = dependency[1]; + graph.addEdge(first, second); + } + + return graph; + } + + public static List orderProjects(List projects) { + + LinkedList queue = new LinkedList<>(); + for (Project project : projects) { + if (project.getParents().size() == 0) { + queue.add(project); + } + } + + List result = new ArrayList<>(); + while(!queue.isEmpty()) { + Project r = queue.removeFirst(); + if(!r.isProcessed() && r.getParents().stream().allMatch(Project::isProcessed)) { + r.setProcessed(true); + result.add(r); + for (Project project : r.getChildren()) { + if(!project.isProcessed()) { + queue.add(project); + } + } + } + + + } + return result; + } + + public static List findBuildOrder(String[] projects, String[][] dependencies) { + Graph graph = buildGraph(projects, dependencies); + return orderProjects(graph.getNodes()); + } + + public static List buildOrderWrapper(String[] projects, String[][] dependencies) { + List buildOrder = findBuildOrder(projects, dependencies); + if (buildOrder == null) return null; + List buildOrderString = buildOrder.stream().map(Project::getName).collect(Collectors.toList()); + return buildOrderString; + } + + public static void main(String[] args) { + String[] projects = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}; + String[][] dependencies = { + {"a", "b"}, + {"b", "c"}, + {"a", "c"}, + {"a", "c"}, + {"d", "e"}, + {"b", "d"}, + {"e", "f"}, + {"a", "f"}, + {"h", "i"}, + {"h", "j"}, + {"i", "j"}, + {"g", "j"}}; + List buildOrder = buildOrderWrapper(projects, dependencies); + if (buildOrder.isEmpty()) { + System.out.println("Circular Dependency."); + } else { + for (String s : buildOrder) { + System.out.println(s); + } + } + } + +}