Skip to content

Instantly share code, notes, and snippets.

@maksverver
Created December 13, 2022 17:42
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 maksverver/822f6bf71ef5e60e97e9dbeefe4458a9 to your computer and use it in GitHub Desktop.
Save maksverver/822f6bf71ef5e60e97e9dbeefe4458a9 to your computer and use it in GitHub Desktop.
package com.janoz.aoc.y2022.day13;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Package implements Comparable<Package> {
private final AList contents;
public Package(String data) {
contents = new AList(parseList(new CharIterator(data)));
}
public String asString() {
return asString(contents.asList());
}
private String asString(List<ListOrInt> l) {
StringBuilder sb = new StringBuilder();
sb.append('[');
for (int i=0; i<l.size(); i++) {
if (i!=0) {
sb.append(',');
}
if (!l.get(i).isList()) {
sb.append(l.get(i).getInt());
} else {
sb.append(asString(l.get(i).asList()));
}
}
sb.append(']');
return sb.toString();
}
private List<ListOrInt> parseList(CharIterator it) {
List<ListOrInt> currentList = new ArrayList<>();
it.pop(); // pop [
while (it.peek()!=']') {
if (it.peek() == '[') {
currentList.add(new AList(parseList(it)));
} else {
currentList.add(new AnInt(it.popInt()));
}
if (it.peek() == ',') it.pop();
}
it.pop();
return currentList;
}
@Override
public int compareTo(Package o) {
return compare(contents, o.contents);
}
private static int compare(ListOrInt a, ListOrInt b) {
if (a.isList() || b.isList()) {
Iterator<ListOrInt> i1 = a.asList().iterator();
Iterator<ListOrInt> i2 = b.asList().iterator();
while (i1.hasNext() && i2.hasNext()) {
int c = compare(i1.next(), i2.next());
if (c != 0) return c;
}
if (i1.hasNext()) return +1;
if (i2.hasNext()) return -1;
return 0;
} else {
return Integer.compare(a.getInt(), b.getInt());
}
}
private static class CharIterator {
int curpos;
String data;
CharIterator(String data) {
this.data = data;
curpos = 0;
}
char peek() {
return data.charAt(curpos);
}
char pop() {
return data.charAt(curpos++);
}
int popInt() {
int i=0;
while (peek() >= '0' && peek() <= '9') {
i = i * 10;
i = i + (pop() - '0');
}
return i;
}
}
private static abstract class ListOrInt {
abstract boolean isList();
abstract int getInt();
abstract List<ListOrInt> asList();
}
private static class AList extends ListOrInt {
private final List<ListOrInt> l;
AList(List<ListOrInt> l) {
this.l = l;
}
boolean isList() {
return true;
}
int getInt() {
throw new UnsupportedOperationException("Cannot convert a list to an int");
}
List<ListOrInt> asList() {
return l;
}
}
private static class AnInt extends ListOrInt {
private final int i;
private List<ListOrInt> l;
AnInt(int i) {
this.i = i;
}
boolean isList() {
return false;
}
int getInt() {
return i;
}
List<ListOrInt> asList() {
if (l == null) {
// Cache it for later.
l = Collections.singletonList(this);
}
return l;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment