HR자바 Java Visitor Pattern

개요[ | ]

HR자바 Java Visitor Pattern
해커랭크 Java
# 문제 비고
HR자바 Advanced e
53 HR자바 Java Varargs - Simple Addition
54 HR자바 Java Reflection - Attributes
55 HR자바 Can You Access?
56 HR자바 Prime Checker
57 HR자바 Java Factory Pattern
58 HR자바 Java Singleton Pattern
59 HR자바 Java Visitor Pattern
60 HR자바 Java Annotations
61 HR자바 Covariant Return Types
62 HR자바 Java Lambda Expressions
63 HR자바 Java MD5
64 HR자바 Java SHA-256

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

import java.util.ArrayList;
import java.util.Scanner;

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 ArrayList<Tree> 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 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() == Color.RED) {
            result = (result * node.getValue()) % M;
        }
    }
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.RED) {
            result = (result * leaf.getValue()) % M;
        }
    }
}

class FancyVisitor extends TreeVis {
    private int nonLeafEvenDepthSum = 0;
    private int greenLeavesSum = 0;
    public int getResult() {
        return Math.abs(nonLeafEvenDepthSum - greenLeavesSum);
    }
    public void visitNode(TreeNode node) {
        if (node.getDepth() % 2 == 0) {
            nonLeafEvenDepthSum += node.getValue();
        }
    }
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.GREEN) {
            greenLeavesSum += leaf.getValue();
        }
    }
}

public class Solution {
    private static int[] nums;
    private static Color[] colors;
    private static HashMap<Integer, HashSet<Integer>> map;
    
    public static Tree solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        nums = new int[n];
        colors = new Color[n];
        map = new HashMap<>(n);
        for (int i = 0; i < n; i++) {
            nums[i] = sc.nextInt();
        }
        for (int i = 0; i < n; i++) {
            colors[i] = sc.nextInt() == 0 ? Color.RED : Color.GREEN;
        }
        
        for (int i = 0; i < n - 1; i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            
            HashSet<Integer> uNeighbors = map.get(u);
            if (uNeighbors == null) {                
                uNeighbors = new HashSet<>();
                map.put(u, uNeighbors);
            }
            HashSet<Integer> vNeighbors = map.get(v);
            if (vNeighbors == null) {
                vNeighbors = new HashSet<>();
                map.put(v, vNeighbors);
            }
            uNeighbors.add(v);
            vNeighbors.add(u);
        }
        sc.close();
        
        if (n == 1) {
            return new TreeLeaf(nums[0], colors[0], 0);
        }
        TreeNode root = new TreeNode(nums[0], colors[0], 0);
        addChildren(root, 1);
        return root;
    }

    private static void addChildren(TreeNode parent, Integer parentNum) {
        for (int treeNum: map.get(parentNum)) {
            map.get(treeNum).remove(parentNum);
            HashSet<Integer> grandChildren = map.get(treeNum);
            if ( grandChildren == null || grandChildren.isEmpty() ) {
                TreeLeaf leaf = new TreeLeaf(nums[treeNum-1], colors[treeNum-1], parent.getDepth()+1);
                parent.addChild(leaf);
                continue;
            }
            TreeNode node = new TreeNode(nums[treeNum-1], colors[treeNum-1], parent.getDepth()+1);
            addChildren(node, treeNum);
            parent.addChild(node);
        }
    }
    public static void main(String[] args) {
      	Tree root = solve();
		SumInLeavesVisitor vis1 = new SumInLeavesVisitor();
      	ProductOfRedNodesVisitor vis2 = new ProductOfRedNodesVisitor();
      	FancyVisitor vis3 = new FancyVisitor();

      	root.accept(vis1);
      	root.accept(vis2);
      	root.accept(vis3);

      	int res1 = vis1.getResult();
      	int res2 = vis2.getResult();
      	int res3 = vis3.getResult();

      	System.out.println(res1);
     	System.out.println(res2);
    	System.out.println(res3);
	}
}
문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}