diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c995aa5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.debug.settings.onBuildFailureProceed": true +} \ No newline at end of file diff --git a/src/Practice.java b/src/Practice.java index 1dcdfb1..467fc31 100644 --- a/src/Practice.java +++ b/src/Practice.java @@ -1,5 +1,11 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.Set; public class Practice { @@ -25,7 +31,27 @@ public class Practice { * @return the number of vertices with odd values reachable from the starting vertex */ public static int oddVertices(Vertex starting) { - return 0; + Set visited = new HashSet<>(); + return oddHelper(starting, visited); + } + + public static int oddHelper(Vertex starting, Set visited) { + if(starting == null) return 0; + if(visited.contains(starting.data)) return 0; + + int count = 0; + + visited.add(starting.data); + + if(starting.data % 2 == 1) { + count = 1; + } + + for(Vertex next : starting.neighbors) { + count += oddHelper(next, visited); + } + + return count; } /** @@ -48,9 +74,25 @@ public static int oddVertices(Vertex starting) { */ public static List sortedReachable(Vertex starting) { // Unimplemented: perform a depth-first search and sort the collected values. - return null; + if(starting == null) return new ArrayList<>(); + Set> visited = new HashSet<>(); + List result = new ArrayList<>(); + sortHelper(starting, visited, result); + Collections.sort(result); + return result; } + public static void sortHelper(Vertex starting, Set> visited, List result) { + if(visited.contains(starting)) return; + + visited.add(starting); + result.add(starting.data); + + for(Vertex neighbor : starting.neighbors) { + sortHelper(neighbor, visited, result); + } + } + /** * Returns a sorted list of all values reachable from the given starting vertex in the provided graph. * The graph is represented as a map where each key is a vertex and its corresponding value is a set of neighbors. @@ -60,9 +102,27 @@ public static List sortedReachable(Vertex starting) { * @param graph a map representing the graph * @param starting the starting vertex value * @return a sorted list of all reachable vertex values - */ + */ public static List sortedReachable(Map> graph, int starting) { - return null; + if(graph == null || !graph.containsKey(starting)) return new ArrayList<>(); + + Set visited = new HashSet<>(); + List result = new ArrayList<>(); + sortHelper(graph, starting, visited, result); + Collections.sort(result); + return result; + } + + public static void sortHelper(Map> graph, int starting, Set visited, + List result) { + if(visited.contains(starting)) return; + + visited.add(starting); + result.add(starting); + + for(var neighbor : graph.get(starting)) { + sortHelper(graph, neighbor, visited, result); + } } /** @@ -80,9 +140,33 @@ public static List sortedReachable(Map> graph, in * @return true if there is a two-way connection between v1 and v2, false otherwise */ public static boolean twoWay(Vertex v1, Vertex v2) { - return false; + if (v1 == null || v2 == null) return false; + if (v1.equals(v2)) return true; + + return canReach(v1, v2) && canReach(v2, v1); +} + + public static boolean canReach(Vertex start, Vertex target) { + return twoWayHelper(start, target, new HashSet<>()); } + public static boolean twoWayHelper(Vertex current, Vertex target, Set> visited) { + if (current == null) return false; + if (current.equals(target)) return true; + if (visited.contains(current)) return false; + + visited.add(current); + + for (Vertex neighbor : current.neighbors) { + if (twoWayHelper(neighbor, target, visited)) { + return true; + } + } + + return false; +} + + /** * Returns whether there exists a path from the starting to ending vertex that includes only positive values. * @@ -96,8 +180,28 @@ public static boolean twoWay(Vertex v1, Vertex v2) { * @return whether there exists a valid positive path from starting to ending */ public static boolean positivePathExists(Map> graph, int starting, int ending) { + if (graph == null || !graph.containsKey(starting) || !graph.containsKey(ending)) return false; + if (starting <= 0 || ending <= 0) return false; + if (starting == ending) return true; + + return posHelper(graph, starting, ending, new HashSet<>()); +} + + public static boolean posHelper(Map> graph, int current, int target, Set visited) { + if (current == target) return true; + if (visited.contains(current)) return false; + + visited.add(current); + + for (int neighbor : graph.getOrDefault(current, Collections.emptySet())) { + if (neighbor > 0 && posHelper(graph, neighbor, target, visited)) { + return true; + } + } + return false; - } +} + /** * Returns true if a professional has anyone in their extended network (reachable through any number of links) @@ -109,6 +213,35 @@ public static boolean positivePathExists(Map> graph, int s * @return true if a person in the extended network works at the specified company, false otherwise */ public static boolean hasExtendedConnectionAtCompany(Professional person, String companyName) { - return false; + if (person == null || companyName == null) return false; + + Set visited = new HashSet<>(); + + return bfsHelper(person, companyName, visited); + + } + + public static boolean bfsHelper(Professional person, String companyName, Set visited) { + + Queue queue = new LinkedList<>(); + + queue.add(person); + visited.add(person); + + while (!queue.isEmpty()) { + Professional current = queue.poll(); + if (companyName.equals(current.getCompany())) { + return true; + } + + for (Professional connection : current.getConnections()) { + if (!visited.contains(connection)) { + visited.add(connection); + queue.add(connection); + } + } + } + + return false; + } } -}