Java Visitor Pattern

Sort by

recency

|

193 Discussions

|

  • + 0 comments

    java8 working f9- import java.util.*;

    enum Color { RED, GREEN }

    abstract class Tree { private int value; private Color color; private int depth;

    public Tree(int value, Color color, int depth) {
        this.value = value;
        this.color = color;
        this.depth = depth;
    }
    
    public int getValue() {
        return value;
    }
    
    public Color getColor() {
        return color;
    }
    
    public int getDepth() {
        return depth;
    }
    
    public abstract void accept(TreeVis visitor);
    

    }

    class TreeNode extends Tree { private List children = new ArrayList<>();

    public TreeNode(int value, Color color, int depth) {
        super(value, color, depth);
    }
    
    public void accept(TreeVis visitor) {
        visitor.visitNode(this);
        for (Tree child : children) {
            child.accept(visitor);
        }
    }
    
    public void addChild(Tree child) {
        children.add(child);
    }
    

    }

    class TreeLeaf extends Tree { public TreeLeaf(int value, Color color, int depth) { super(value, color, depth); }

    public void accept(TreeVis visitor) {
        visitor.visitLeaf(this);
    }
    

    }

    abstract class TreeVis { public abstract int getResult(); public abstract void visitNode(TreeNode node); public abstract void visitLeaf(TreeLeaf leaf); }

    class SumInLeavesVisitor extends TreeVis { private int sum = 0;

    public int getResult() {
        return sum;
    }
    
    public void visitNode(TreeNode node) {
        // Do nothing
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        sum += leaf.getValue();
    }
    

    }

    class ProductRedNodesVisitor extends TreeVis { private long product = 1; private final int MOD = 1000000007;

    public int getResult() {
        return (int) product;
    }
    
    public void visitNode(TreeNode node) {
        if (node.getColor() == Color.RED) {
            product = (product * node.getValue()) % MOD;
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.RED) {
            product = (product * leaf.getValue()) % MOD;
        }
    }
    

    }

    class FancyVisitor extends TreeVis { private int evenDepthNonLeafSum = 0; private int greenLeafSum = 0;

    public int getResult() {
        return Math.abs(evenDepthNonLeafSum - greenLeafSum);
    }
    
    public void visitNode(TreeNode node) {
        if (node.getDepth() % 2 == 0) {
            evenDepthNonLeafSum += node.getValue();
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.GREEN) {
            greenLeafSum += leaf.getValue();
        }
    }
    

    }

    public class Solution { public static Tree solve() { Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int[] values = new int[n]; byte[] colors = new byte[n];

        for (int i = 0; i < n; i++) {
            values[i] = scan.nextInt();
        }
    
        for (int i = 0; i < n; i++) {
            colors[i] = scan.nextByte();
        }
    
        Map<Integer, List<Integer>> adj = new HashMap<>();
        for (int i = 0; i < n; i++) {
            adj.put(i, new ArrayList<>());
        }
    
        for (int i = 0; i < n - 1; i++) {
            int u = scan.nextInt() - 1;
            int v = scan.nextInt() - 1;
            adj.get(u).add(v);
            adj.get(v).add(u);
        }
    
        scan.close();
        boolean[] visited = new boolean[n];
        return buildTree(0, 0, values, colors, adj, visited);
    }
    
    public static Tree buildTree(int index, int depth, int[] values, byte[] colors, Map<Integer, List<Integer>> adj, boolean[] visited) {
        visited[index] = true;
        Color color = colors[index] == 0 ? Color.RED : Color.GREEN;
        List<Integer> children = adj.get(index);
        boolean isLeaf = true;
    
        List<Tree> childTrees = new ArrayList<>();
        for (int child : children) {
            if (!visited[child]) {
                isLeaf = false;
                childTrees.add(buildTree(child, depth + 1, values, colors, adj, visited));
            }
        }
    
        if (isLeaf) {
            return new TreeLeaf(values[index], color, depth);
        } else {
            TreeNode node = new TreeNode(values[index], color, depth);
            for (Tree child : childTrees) {
                node.addChild(child);
            }
            return node;
        }
    }
    
    public static void main(String[] args) {
        Tree root = solve();
    
        SumInLeavesVisitor vis1 = new SumInLeavesVisitor();
        ProductRedNodesVisitor vis2 = new ProductRedNodesVisitor();
        FancyVisitor vis3 = new FancyVisitor();
    
        root.accept(vis1);
        root.accept(vis2);
        root.accept(vis3);
    
        System.out.println(vis1.getResult());
        System.out.println(vis2.getResult());
        System.out.println(vis3.getResult());
    }
    

    }

  • + 0 comments
    class SumInLeavesVisitor extends TreeVis {
        private int sum = 0;
    
        public int getResult() {
            return sum;
        }
    
        public void visitNode(TreeNode node) {
            // No action needed for internal nodes in this visitor
        }
    
        public void visitLeaf(TreeLeaf leaf) {
            sum += leaf.getValue();
        }
    }
    
    class ProductOfRedNodesVisitor extends TreeVis {
        private double product = 1;
    
        public int getResult() {
            return (int) product;
        }
    
        public void visitNode(TreeNode node) {
            increaseProduct(node);
        }
    
        public void visitLeaf(TreeLeaf leaf) {
            increaseProduct(leaf);
        }
    
        private void increaseProduct(Tree tree) {
            if (tree.getColor() == Color.RED) {
                product = (product * tree.getValue()) % (Math.pow(10, 9) + 7);
            }
        }
    }
    
    class FancyVisitor extends TreeVis {
        private int nonLeafNodeSum = 0;
        private int greenLeafSum = 0;
    
        public int getResult() {
            return Math.abs(nonLeafNodeSum - greenLeafSum);
        }
    
        public void visitNode(TreeNode node) {
            if (node.getDepth() % 2 == 0) {
                nonLeafNodeSum += node.getValue();
            }
        }
    
        public void visitLeaf(TreeLeaf leaf) {
            if (leaf.getColor() == Color.GREEN) {
                greenLeafSum += leaf.getValue();
            }
        }
    }
    
    public class Solution {
      
        public static Tree solve() {
            Scanner scan = new Scanner(System.in);
            int n = Integer.parseInt(scan.nextLine());
            String valuesLine = scan.nextLine();
            String colorsLine = scan.nextLine();
    
            String[] valuesStr = valuesLine.split(" ");
            int[] values = new int[n];
    
            for (int i = 0; i < n; i++) {
                values[i] = Integer.parseInt(valuesStr[i]);
            }
    
            String[] colorsStr = colorsLine.split(" ");
            byte[] colors = new byte[n];
            
            for (int i = 0; i < n; i++) {
                colors[i] = (byte) Integer.parseInt(colorsStr[i]);
            }
    
            Map<Integer, List<Integer>> adj = new HashMap<>();
            boolean[] visited = new boolean[n];
    
            for (int i = 0; i < n; i++) {
                adj.put(i, new ArrayList<Integer>());
            }
    
            while (scan.hasNextInt()) {
                int u = scan.nextInt() - 1;
                int v = scan.nextInt() - 1;
                adj.get(u).add(v);
                adj.get(v).add(u);
            }
    
            scan.close();
            
            return buildTree(0, 0, values, colors, adj, visited);
        }
    
        public static Tree buildTree(
            int index, int depth, int[] values, byte[] colors, Map<Integer, List<Integer>> adj, boolean[] visited
        ) {
            boolean isLeaf = true;
            visited[index] = true;
    
            Color color = colors[index] == 0 ? Color.RED : Color.GREEN;
            List<Integer> children = adj.get(index);
            TreeNode treeNode = new TreeNode(values[index], color, depth);
    
            for (int child : children) {
                if (!visited[child]) {
                    isLeaf = false;
                    Tree childNode = buildTree(child, depth + 1, values, colors, adj, visited);
                    treeNode.addChild(childNode);
                }
            }
    
            if (isLeaf) {
                return new TreeLeaf(values[index], color, depth);
            } else {
                return treeNode;
            }
        }
    
  • + 0 comments

    This problem leads one to believe that the input data is a tree. But in fact, it is an undirected graph. The lack of this information made me waste a lot of time solving the problem.

  • + 0 comments

    Here is Java visitor pattern solution - https://programmingoneonone.com/hackerrank-java-visitor-pattern-problem-solution.html

  • + 1 comment

    class SumInLeavesVisitor extends TreeVis { public int getResult() { //implement this return leavesValuesCounter; }

    public void visitNode(TreeNode node) {
        //implement this
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        //implement this
    
        if (leaf == null) {
            return;
        }
    
        leavesValuesCounter += leaf.getValue();
    }
    

    // private private int leavesValuesCounter = 0; }

    class ProductOfRedNodesVisitor extends TreeVis { public int getResult() { //implement this return productOfRedNodesCounter; }

    public void visitNode(TreeNode node) {
        //implement this
        if (node == null)
            return;
    
        if (node.getColor() == Color.RED) {
            int value = node.getValue();
            value = (value == 0) ? 1 : value;
    
            productOfRedNodesCounter = (int)(((long)productOfRedNodesCounter * value) % MODULE);
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        //implement this
    
        if (leaf == null)
            return;
    
        if (leaf.getColor() == Color.RED) {
            int value = leaf.getValue();
            value = (value == 0) ? 1 : value;
    
            productOfRedNodesCounter = (int)(((long)productOfRedNodesCounter * value) % MODULE);
        }
    }
    
    private int productOfRedNodesCounter = 1;
    final int MODULE = 1000000007;
    

    }

    class FancyVisitor extends TreeVis { public int getResult() { //implement this return Math.abs(sumGreenLeafNodes - sumNonLeafNodes); }

    public void visitNode(TreeNode node) {
        //implement this
        if (node == null)
            return;
    
        if (node.getDepth() % 2 == 0) {
            sumNonLeafNodes += node.getValue();
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        //implement this
    
        if (leaf == null)
            return;
    
        if (leaf.getColor() == Color.GREEN) {
            sumGreenLeafNodes += leaf.getValue();
        }
    }
    
    private int sumNonLeafNodes = 0;
    private int sumGreenLeafNodes = 0;
    

    }

    public class Solution {

    private static boolean isALeaf(List<List<Integer>> adjacencyTable,
                                boolean[] visited, int elementPosition) {
        if (adjacencyTable.get(elementPosition).isEmpty()) {
            return true;
        }
    
        for (int i = 0; i < adjacencyTable.get(elementPosition).size(); i++) {
            Integer recordedValue = adjacencyTable.get(elementPosition).get(i);
            if (!visited[recordedValue]) {
                return false;
            }
        }
    
        return true;
    }
    
    
    private static Tree createTheTree(List<List<Integer>> adjacencyTable,
                                     boolean[] visited, int[] nodeCosts, int[] colors, int parentDepth,
                                     int elementPosition) {
    
        int localDepth = parentDepth + 1;
        if (isALeaf(adjacencyTable, visited, elementPosition)) {
            return new TreeLeaf(nodeCosts[elementPosition],
                    colors[elementPosition] == 1 ? Color.GREEN : Color.RED,
                    localDepth );
        }
    
        TreeNode currentNode = new TreeNode(nodeCosts[elementPosition],
                colors[elementPosition] == 1 ? Color.GREEN : Color.RED,
                localDepth);
    
        visited[elementPosition] = true;
    
        for (int i = 0; i < adjacencyTable.get(elementPosition).size(); i++) {
            Integer recordedValue = adjacencyTable.get(elementPosition).get(i);
            if (!visited[recordedValue]) {
                Tree child = createTheTree(adjacencyTable, visited, nodeCosts, colors,
                        localDepth, recordedValue);
                currentNode.addChild(child);
            }
        }
    
        return currentNode;
    }
    
    
    public static Tree solve() {
        //read the tree from STDIN and return its root as a return value of this function
        Scanner myObj = new Scanner(System.in);
        int nodesCount = myObj.nextInt();
    
        int[] nodeCosts = new int[nodesCount];
        int[] colors = new int[nodesCount];
    
        for (int i = 0; i < nodesCount; i++) {
            nodeCosts[i] = myObj.nextInt();
        }
    
        for (int i = 0; i < nodesCount; i++) {
            colors[i] = myObj.nextInt();
        }
    
        List<List<Integer>> adjacencyTable = new ArrayList<>(nodesCount);
        for (int i = 0; i < nodesCount; i++) {
            adjacencyTable.add(new ArrayList<Integer>());
        }
    
        boolean[] visited = new boolean[nodesCount];
    
        int decrement = nodesCount - 1;
        while (decrement > 0) {
            int u = myObj.nextInt();
            int v = myObj.nextInt();
    
            adjacencyTable.get(u - 1).add(v - 1);
            adjacencyTable.get(v - 1).add(u - 1);
    
            decrement--;
        }
    
        Tree result = createTheTree(adjacencyTable, visited, nodeCosts, colors, -1, 0);
        return result;
    }