Зря я сетовал на загадку прошлого дня. Ох, зря! Парсинг вот этих вот дурных скобочек-в-скобочках — это было форменно издевательство, помноженное на бесконечное уныние.
Просто весь интерес убивает. После решения, вместо удовольствия — только облегчение с мыслью «Хоть бы никогда больше не встретить подобного» 🙂
Да будь там, допустим, валидный JSON — я бы, пожалуй, сдался, и подключил либу. Но костыли с JSONArray, навскидку, не выглядели проще кастомного решения. Что ж, вот оно.
Толстый-толстый класс пакета
class PDU implements Comparable<PDU> {
private final List<PDU> child = new ArrayList<>();
private int val = -1;
private boolean isNum = true;
private final String rawValue;
public PDU(String input) {
this.rawValue = input;
if (!input.startsWith("[")) {
val = Integer.parseInt(input);
} else {
input = input.substring(1, input.length() - 1);
int level = 0;
StringBuilder tmp = new StringBuilder();
for (char c : input.toCharArray()) {
if (c == ',' && level == 0) {
child.add(new PDU(tmp.toString()));
tmp = new StringBuilder();
} else {
level += (c == '[') ? 1 : (c == ']') ? -1 : 0;
tmp.append(c);
}
}
if (!tmp.toString().equals("")) {
child.add(new PDU(tmp.toString()));
}
isNum = false;
}
}
@Override
public int compareTo(PDU other) {
if (isNum && other.isNum) {
return Integer.compare(other.val, val);
}
if (!isNum && !other.isNum) {
for (int i = 0; i < Math.min(child.size(), other.child.size()); i++) {
int val = child.get(i).compareTo(other.child.get(i));
if (val != 0) {
return val;
}
}
return other.child.size() - child.size();
}
PDU pdu1 = isNum ? new PDU("[" + val + "]") : this;
PDU pdu2 = other.isNum ? new PDU("[" + other.val + "]") : other;
return pdu1.compareTo(pdu2);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PDU that = (PDU) o;
return rawValue.equals(that.rawValue);
}
@Override
public int hashCode() {
return Objects.hashCode(rawValue);
}
}
Более-менее компактное решение
static void day13(String puzzleInputUri) throws IOException, InterruptedException {
String[] packets = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines())
.body()
.filter(line -> line.startsWith("["))
.toArray(String[]::new);
int answerPartOne = 0;
List<PDU> broadcast = new ArrayList<>();
for (int i = 0, pairIdx = 1; i < packets.length - 1; i += 2, pairIdx++) {
PDU left = new PDU(packets[i]);
PDU right = new PDU(packets[i+1]);
broadcast.addAll(List.of(left, right));
answerPartOne += left.compareTo(right) > 0 ? pairIdx : 0;
}
System.out.println(answerPartOne);
PDU separator1 = new PDU("[[2]]");
PDU separator2 = new PDU("[[6]]");
broadcast.addAll(List.of(separator1, separator2));
broadcast.sort(Comparator.reverseOrder());
int answerPartTwo = (broadcast.indexOf(separator1) + 1) * (broadcast.indexOf(separator2) + 1);
System.out.println(answerPartTwo);
}
Ладно, спишу это на «несчастливый номер» задачки. Вариация на тему тетриса (из задачи следующего дня) обещает быть интересней.
Исходные данные: https://adventofcode.com/2022/day/13/input