Skip to content

Instantly share code, notes, and snippets.

@PulseBeat02
Last active December 21, 2020 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PulseBeat02/96ab1f39a29c8b4a1724fda77bc44492 to your computer and use it in GitHub Desktop.
Save PulseBeat02/96ab1f39a29c8b4a1724fda77bc44492 to your computer and use it in GitHub Desktop.
MonsterMessages.java
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