Message 2

You might also like

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 5

import java.io.

*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

/*
* Complete the function below.
*/
/*
Browser needs TCPIP and HTML
TCPIP needs NETCARD
HTML needs nothing

Remove TCPIP. Fail, because Browser needs TCPIP


Remove Browser, Success, because nothing needs browser
- Remove all dependencies of browser
- Remove TCPIP, Success. Because nothing needs TCPIP
- Remove HTML, Success. because nothing needs HTML
*/

public static class DependencyManager {


public class Component {
String name;
List<Component> dependencies; //This problem doesn't say it, but order
is important
List<Component> dependers; // This problem doesn't specify, but order
is important
boolean directlyInstalled;

public Component(String name) {


this.name = name;
this.dependencies = new ArrayList<>();
this.dependers = new ArrayList<>();
this.directlyInstalled = false;
}

public Component() {}

public List<Component> getDependencies() {


return this.dependencies;
}

public void addDependency(Component dependency) {


this.dependencies.add(dependency);
}

public List<Component> getDependers() {


return this.dependers;
}

public void addDepender(Component depender) {


this.dependers.add(depender);
}

public String getName() {


return this.name;
}

public void setName(String name) {


this.name = name;
}

public boolean getDirectlyInstalled() {


return this.directlyInstalled;
}

public void setDirectlyInstalled(boolean directlyInstalled) {


this.directlyInstalled = directlyInstalled;
}
}

/*
We use a Hash Set to retrieve components and check for their
installation with O(1) speed
We use a list for InstalledOrder because a hidden testcase is to return
the correct order
We use a Hash Table to keep track of existing dependency components
(nodes) and attribute them to their dependors or dependencies
*/

Set<String> installedComponents; // Hash Set of Installed components


List<String> installedOrder; // Order of installed components
Map<String, Component> components; // Hash Table of Existing components
(Dependencies)

public DependencyManager() {
this.installedComponents = new HashSet<>();
this.installedOrder = new ArrayList<>();
this.components = new HashMap<>();
}

public void depend (String itemName, List<String> dependencies) {


if (itemName == null || itemName.length() == 0 || dependencies == null)
return; // Improvement: Throw exception

Component child = components.getOrDefault(itemName, new


Component(itemName));

for (String parent : dependencies) {


if (!components.containsKey(parent)) components.put(parent, new
Component(parent));
Component parentItem = components.get(parent);

if (parentItem.getDependencies().contains(child)) {
System.out.println(parentItem.getName() + " depends on " +
itemName + ", ignoring command");
continue;
}

child.getDependencies().add(parentItem);
parentItem.getDependers().add(child); //Doubly linked mapping
}

components.put(itemName, child);
}
public void install (String itemName, boolean directlyInstalled) {
if (itemName == null || itemName.length() == 0) return; // Improvement:
Throw exception
if (installedComponents.contains(itemName)) {
System.out.println(itemName + " is already installed");
return; // Improvement: Throw exception
}

if (!components.containsKey(itemName)) components.put(itemName, new


Component(itemName));

Component item = components.get(itemName);


List<Component> itemDeps = item.getDependencies();
item.setDirectlyInstalled(directlyInstalled); // We should only remove
dependencies that were not directly installed by user

for (Component dependency : itemDeps) {


if (!installedComponents.contains(dependency.name)) {
install(dependency.getName(), false);
}
}
System.out.println(String.format("Installing %s", itemName));
installedComponents.add(itemName);
installedOrder.add(itemName);
}

public void remove (String itemName) {


if (itemName == null || itemName.length() == 0) return; // Improvement:
Throw exception
if (!installedComponents.contains(itemName)) {
System.out.println(String.format("%s is not installed", itemName));
return; //Improvement: Throw exception
}

Component item = components.get(itemName);


List<Component> itemDependers = item.getDependers();
for (Component depender : itemDependers) {
if (installedComponents.contains(itemName)) {
System.out.println(itemName + " is still needed");
return; //Improvement: Throw exception
}
}

System.out.println("Removing " + itemName);


installedComponents.remove(itemName);
installedOrder.remove(itemName);
List<Component> itemDeps = item.getDependencies();

for (Component dependency : itemDeps) {


List<Component> dependers = dependency.getDependers();
dependers.remove(item);
if (!dependency.directlyInstalled && dependers.isEmpty()) {
System.out.println("Removing " + dependency.getName());
installedComponents.remove(dependency.getName());
installedOrder.remove(dependency.getName());
}
}
}
public void list() {
for (String item : installedOrder) {
System.out.println(item);
}
}
}

static void doIt(String[] inputs) {


DependencyManager depManager = new DependencyManager();

for (String commandStr : inputs) {


String[] split = commandStr.split("\\s+");
String cmd = split[0]; // First word is always the command
String mainItem = "";

switch(cmd){
case("DEPEND"):
mainItem = split[1]; // Component to run commands on
StringBuilder echo = new StringBuilder();
echo.append(cmd + " " + mainItem);
List<String> dependencies = new ArrayList<>();
for (int i = 2; i < split.length; i++) {
dependencies.add(split[i]);
echo.append(" " + split[i]);
}

System.out.println(echo.toString());
depManager.depend(mainItem, dependencies);
break;
case("INSTALL"):
mainItem = split[1]; // Component to run commands on
System.out.println(String.format("%s %s", cmd, mainItem));
depManager.install(mainItem, true);
break;
case("REMOVE"):
mainItem = split[1]; // Component to run commands on
System.out.println(String.format("%s %s", cmd, mainItem));
depManager.remove(mainItem);
break;
case("LIST"):
System.out.println(cmd);
depManager.list();
break;
case("END"):
System.out.println(cmd);
break;
default:
System.out.println("Invalid command. Skipping"); //
Improvement: Throw Exception
break;
}
}
}

public static void main(String[] args){


Scanner in = new Scanner(System.in);

int _input_size = 0;
_input_size = Integer.parseInt(in.nextLine().trim());
String[] _input = new String[_input_size];
String _input_item;
for(int _input_i = 0; _input_i < _input_size; _input_i++) {
try {
_input_item = in.nextLine();
} catch (Exception e) {
_input_item = null;
}
_input[_input_i] = _input_item;
}

doIt(_input);
}
}

You might also like