Last active
December 21, 2020 14:01
-
-
Save PulseBeat02/96ab1f39a29c8b4a1724fda77bc44492 to your computer and use it in GitHub Desktop.
MonsterMessages.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.ArrayDeque; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Queue; | |
import java.util.Set; | |
public class MonsterMessages { | |
private static Queue<Rule> queue; | |
private static Set<List<Rule>> unique; | |
public static void main(String[] args) throws IOException { | |
BufferedReader br = new BufferedReader(new FileReader("monstermessages.txt")); | |
Map<Integer, Rule> rules = new HashMap<>(); | |
String currentLine = br.readLine(); | |
while (!currentLine.isEmpty()) { | |
String[] bits = currentLine.split(":"); | |
int id = Integer.parseInt(bits[0]); | |
if (bits[1].charAt(1) == '"') { | |
rules.put(id, new MatchingRule(id, bits[1].charAt(2))); | |
} else { | |
if (bits[1].contains("|")) { | |
String[] pipes = bits[1].split("\\|"); | |
List<List<Integer>> rulesSet = new ArrayList<>(); | |
for (int j = 0; j < pipes.length; j++) { | |
List<Integer> currentRules = new ArrayList<>(); | |
for (String child : pipes[j].trim().split(" ")) { | |
currentRules.add(Integer.parseInt(child)); | |
} | |
rulesSet.add(currentRules); | |
} | |
rules.put(id, new SubRuleOr(id, rulesSet)); | |
} else { | |
String[] first = bits[1].trim().split(" "); | |
List<Integer> children = new ArrayList<>(); | |
for (String str : first) { | |
children.add(Integer.parseInt(str)); | |
} | |
rules.put(id, new SubRule(id, children)); | |
} | |
} | |
currentLine = br.readLine(); | |
} | |
currentLine = br.readLine(); | |
int count = 0; | |
while (currentLine != null) { | |
char[] chars = currentLine.toCharArray(); | |
List<Character> list = new ArrayList<>(); | |
for (char c : chars) { | |
list.add(c); | |
} | |
queue = new ArrayDeque<>(); | |
unique = new HashSet<>(); | |
if (matchesRules(rules, rules.get(0), list) && list.size() == 0) { | |
count++; | |
} | |
if (queue.size() == 1 && currentLine.equals(concatenate(list))) { | |
count++; | |
} | |
currentLine = br.readLine(); | |
} | |
br.close(); | |
System.out.println("Part One: " + count); | |
} | |
private static String concatenate(List<Character> chars) { | |
StringBuilder sb = new StringBuilder(); | |
for (char c : chars) { | |
sb.append(c); | |
} | |
return sb.toString(); | |
} | |
private static boolean matchesRules(Map<Integer, Rule> rules, Rule rule, List<Character> query) { | |
if (rule instanceof MatchingRule) { | |
MatchingRule matchingRule = (MatchingRule) rule; | |
if (matchingRule.character == query.get(0)) { | |
query.remove(0); | |
return true; | |
} | |
} else { | |
List<List<Integer>> allRules = new ArrayList<>(); | |
if (rule instanceof SubRule) { | |
allRules.add(((SubRule)rule).children); | |
} else if (rule instanceof SubRuleOr) { | |
allRules = new ArrayList<>(((SubRuleOr)rule).children); | |
} | |
for (List<Integer> allRule : allRules) { | |
boolean matches = true; | |
List<Character> temp = new ArrayList<>(query); | |
for (int child : allRule) { | |
queue.add(rule); | |
Rule childRule = rules.get(child); | |
if (!matchesRules(rules, childRule, temp)) { | |
matches = false; | |
queue.remove(childRule); | |
} | |
} | |
if (matches) { | |
int size = query.size(); | |
while (size > temp.size()) { | |
query.remove(0); | |
size--; | |
} | |
if (size == 0) { | |
unique.add(new ArrayList<Rule>(queue)); | |
} | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
private static class Rule { | |
private final int id; | |
public Rule(int id) { | |
this.id = id; | |
} | |
} | |
private static class MatchingRule extends Rule { | |
private final char character; | |
public MatchingRule(int id, char c) { | |
super(id); | |
this.character = c; | |
} | |
} | |
private static class SubRule extends Rule { | |
private final List<Integer> children; | |
public SubRule(int id, List<Integer> children) { | |
super(id); | |
this.children = children; | |
} | |
} | |
private static class SubRuleOr extends Rule { | |
private final List<List<Integer>> children; | |
public SubRuleOr(int id, List<List<Integer>> children) { | |
super(id); | |
this.children = children; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment