Java Visitor Pattern Hackerrank Solution

Java Visitor Pattern Hackerrank Solution
Java Visitor Pattern Hackerrank Solution

Java Visitor Pattern Hackerrank Solution

 In this problem you must NOT generate any output on your own. Any such solution will be considered as being against the rules and its author will be disqualified. The output of your solution must be generated by the uneditable code provided for you in the solution template.

An important concept in Object-Oriented Programming is the open/closed principle, which means writing code that is open to extension but closed to modification. In other words, new functionality should be added by writing an extension for the existing code rather than modifying it and potentially breaking other code that uses it. This challenge simulates a real-life problem where the open/closed principle can and should be applied.

Tree class implementing a rooted tree is provided in the editor. It has the following publicly available methods:

  • getValue(): Returns the value stored in the node.
  • getColor(): Returns the color of the node.
  • getDepth(): Returns the depth of the node. Recall that the depth of a node is the number of edges between the node and the tree’s root, so the tree’s root has depth 0 and each descendant node’s depth is equal to the depth of its parent node +1.

In this challenge, we treat the internal implementation of the tree as being closed to modification, so we cannot directly modify it; however, as with real-world situations, the implementation is written in such a way that it allows external classes to extend and build upon its functionality. More specifically, it allows objects of the TreeVis class (a Visitor Design Pattern) to visit the tree and traverse the tree structure via the accept method.

There are two parts to this challenge.

Part I: Implement Three Different Visitors

Each class has three methods you must write implementations for:

  1. getResult(): Return an integer denoting the result, which is different for each class:
    • The SumInLeavesVisitor implementation must return the sum of the values in the tree’s leaves only.
    • The ProductRedNodesVisitor implementation must return the product of values stored in all red nodes, including leaves, computed modulo 10^9+7. Note that the product of zero values is equal to 1.
    • The FancyVisitor implementation must return the absolute difference between the sum of values stored in the tree’s non-leaf nodes at even depth and the sum of values stored in the tree’s green leaf nodes. Recall that zero is an even number.
  2. visitNode(TreeNode node): Implement the logic responsible for visiting the tree’s non-leaf nodes such that the getResult method returns the correct  for the implementing class’ visitor.
  3. visitLeaf(TreeLeaf leaf): Implement the logic responsible for visiting the tree’s leaf nodes such that the getResult method returns the correct result for the implementing class’ visitor.

Part II: Read and Build the Tree

Read the -node tree, where each node is numbered from 1 to n. The tree is given as a list of node values (x1,x2,…,xn), a list of node colors (c1,c2,…,cn), and a list of edges. Construct this tree as an instance of the Tree class. The tree is always rooted at node number 1.

Your implementations of the three visitor classes will be tested on the tree you built from the given input.

Input Format

The first line contains a single integer,n , denoting the number of nodes in the tree. The second line contains n space-separated integers describing the respective values of x1,x2,..,xn.
The third line contains n space-separated binary integers describing the respective values of . Each  denotes the color of the  node, where  denotes red and  denotes green.
Each of the  subsequent lines contains two space-separated integers,  and , describing an edge between nodes  and .

Output Format

Do not print anything to stdout, as this is handled by locked stub code in the editor. The three getResult() methods provided for you must return an integer denoting the  for that class’ visitor (defined above). Note that the value returned by ProductRedNodesVisitor‘s getResult method must be computed modulo .

Sample Input

5
4 7 2 5 12
0 1 0 0 1
1 2
1 3
3 4
3 5

Sample Output

24
40
15

Code Solution:

//Java Visitor Pattern Hackerrank Solution

class SumInLeavesVisitor extends TreeVis {

private int result = 0;

public int getResult() {
    return result;
}

public void visitNode(TreeNode node) {
}

public void visitLeaf(TreeLeaf leaf) {
    result += leaf.getValue();
}
}

class ProductOfRedNodesVisitor extends TreeVis {

private long result = 1;
private final int M = 1000000007;

public int getResult() {
    return (int) result;
}

public void visitNode(TreeNode node) {
    if(node.getColor().equals(Color.RED)) {
        result = (result * node.getValue()) % M;
    }
}

public void visitLeaf(TreeLeaf leaf) {
    if(leaf.getColor().equals(Color.RED)) {
        result = (result * leaf.getValue()) % M;
    }
}
}

class FancyVisitor extends TreeVis {

private int evenDepthNonLeavesSum = 0;
private int greenLeavesSum = 0;

public int getResult() {
    return Math.abs(evenDepthNonLeavesSum - greenLeavesSum);
}

public void visitNode(TreeNode node) {
    if(node.getDepth() % 2 == 0)
        evenDepthNonLeavesSum += node.getValue();
}

public void visitLeaf(TreeLeaf leaf) {
    if(leaf.getColor().equals(Color.GREEN))
        greenLeavesSum += leaf.getValue();
}
}

public class Solution {

private static int nodeValues[];
private static Color nodeColors[];
private static Map<Integer, Set<Integer>> nodesMap = new HashMap<>();

public static Tree solve() {

    Scanner in = new Scanner(System.in);

    int numberOfNodes = in.nextInt();

    nodeValues = new int[numberOfNodes];
    for(int index = 0; index < numberOfNodes; index++) {
        nodeValues[index] = in.nextInt();
    }

    nodeColors = new Color[numberOfNodes];
    for(int index = 0; index < numberOfNodes; index++) {
        nodeColors[index] = (in.nextInt() == 0) ? Color.RED : Color.GREEN;
    }

    Tree rootNode;
    if(numberOfNodes == 1) {
        rootNode = new TreeLeaf(nodeValues[0], nodeColors[0], 0);
    }
    else {
        for(int index = 0; index < (numberOfNodes - 1); index++) {
            int u = in.nextInt();
            int v = in.nextInt();
            Set<Integer> uEdges = nodesMap.get(u);
            if(uEdges == null) {
                uEdges = new HashSet<>();
            }
            uEdges.add(v);
            nodesMap.put(u, uEdges);
            Set<Integer> vEdges = nodesMap.get(v);
            if(vEdges == null) {
                vEdges = new HashSet<>();
            }
            vEdges.add(u);
            nodesMap.put(v, vEdges);
        }

        rootNode = new TreeNode(nodeValues[0], nodeColors[0], 0);
        Set<Integer> rootEdges = nodesMap.get(1);
        Iterator<Integer> rootIterator = rootEdges.iterator();
        while(rootIterator.hasNext()) {
            Integer nodeIdentifier = rootIterator.next();
            nodesMap.get(nodeIdentifier).remove(1);
            createEdge(rootNode, nodeIdentifier);
        }
    }

    return rootNode;
}

private static void createEdge(Tree parentNode, Integer nodeIdentifier) {

    Set<Integer> nodeEdges = nodesMap.get(nodeIdentifier);
    boolean hasChild = false;
    if(nodeEdges != null && !nodeEdges.isEmpty())
        hasChild = true;

    if(hasChild) {
        TreeNode node = new TreeNode(nodeValues[nodeIdentifier - 1], nodeColors[nodeIdentifier - 1], parentNode.getDepth() + 1);
        ((TreeNode) parentNode).addChild(node);
        Iterator<Integer> nodeIterator = nodeEdges.iterator();
        while(nodeIterator.hasNext()) {
            Integer neighborNodeIdentifier = nodeIterator.next();
            nodesMap.get(neighborNodeIdentifier).remove(nodeIdentifier);
            createEdge(node, neighborNodeIdentifier);
        }
    }
    else {
        TreeLeaf leaf = new TreeLeaf(nodeValues[nodeIdentifier - 1], nodeColors[nodeIdentifier - 1], parentNode.getDepth() + 1);
        ((TreeNode) parentNode).addChild(leaf);
    }
}

//Java Visitor Pattern Hackerrank Solution

Disclaimer: This problem is originally created and published by HackerRank, we only provide solutions to this problem. Hence, doesn’t guarantee the truthfulness of the problem. This is only for information purposes.

Leave a Comment