Skip to content

Commit ce6a44e

Browse files
committed
Add year 2022 day13
1 parent 1d3deaf commit ce6a44e

File tree

7 files changed

+747
-1
lines changed

7 files changed

+747
-1
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package dev.linl33.adventofcode.lib;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
import java.nio.ByteBuffer;
6+
import java.nio.charset.StandardCharsets;
7+
8+
public record ByteBufferAsCharSequence(ByteBuffer buffer) implements CharSequence {
9+
@Override
10+
public int length() {
11+
return buffer.remaining();
12+
}
13+
14+
@Override
15+
public char charAt(int index) {
16+
return (char) buffer.get(buffer.position() + index);
17+
}
18+
19+
@Override
20+
public boolean isEmpty() {
21+
return !buffer.hasRemaining();
22+
}
23+
24+
@NotNull
25+
@Override
26+
public CharSequence subSequence(int start, int end) {
27+
var subSequenceStart = buffer.position() + start;
28+
return new ByteBufferAsCharSequence(buffer.slice(subSequenceStart, end - subSequenceStart));
29+
}
30+
31+
@Override
32+
public String toString() {
33+
var arr = new byte[length()];
34+
buffer.duplicate().get(buffer.position(), arr);
35+
return new String(arr, 0, arr.length, StandardCharsets.UTF_8);
36+
}
37+
}

lib/src/main/java/dev/linl33/adventofcode/lib/util/AdventUtil.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package dev.linl33.adventofcode.lib.util;
22

3+
import dev.linl33.adventofcode.lib.ByteBufferAsCharSequence;
4+
import jdk.incubator.vector.ByteVector;
5+
import jdk.incubator.vector.VectorOperators;
36
import org.jetbrains.annotations.NotNull;
47
import org.jetbrains.annotations.Range;
58

69
import java.io.BufferedReader;
10+
import java.lang.foreign.MemorySegment;
11+
import java.nio.ByteBuffer;
712
import java.util.*;
813
import java.util.function.*;
914
import java.util.stream.Collectors;
@@ -151,7 +156,7 @@ private static <T> List<List<T>> generateCombinationsSmall(@NotNull List<T> choi
151156

152157
for (int i = 0; i < choiceCount; i++) {
153158
@SuppressWarnings("unchecked")
154-
var choiceArr = (T[]) new Object[] {choices.get(i)};
159+
var choiceArr = (T[]) new Object[] { choices.get(i) };
155160

156161
allChoices[1 << i] = choiceArr;
157162
prevIdx[i] = 1 << i;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dev.linl33.adventofcode.lib.util;
2+
3+
import dev.linl33.adventofcode.lib.ByteBufferAsCharSequence;
4+
import jdk.incubator.vector.ByteVector;
5+
import jdk.incubator.vector.VectorOperators;
6+
import jdk.incubator.vector.VectorSpecies;
7+
import org.jetbrains.annotations.NotNull;
8+
9+
import java.lang.foreign.MemorySegment;
10+
import java.nio.ByteBuffer;
11+
import java.util.function.Consumer;
12+
13+
public final class VectorIoUtil {
14+
private static final VectorSpecies<Byte> BYTE_SPECIES = ByteVector.SPECIES_MAX;
15+
16+
public static void readLines(@NotNull ByteBuffer byteBuffer, @NotNull Consumer<CharSequence> consumer) {
17+
var charSequence = new ByteBufferAsCharSequence(byteBuffer);
18+
19+
var lineStart = byteBuffer.position();
20+
var lineEnd = byteBuffer.position();
21+
var limit = byteBuffer.limit();
22+
23+
var memSegment = MemorySegment.ofBuffer(byteBuffer);
24+
var newlineVector = ByteVector.broadcast(BYTE_SPECIES, '\n');
25+
26+
for (int i = byteBuffer.position(); i < limit; i += BYTE_SPECIES.length()) {
27+
var mask = BYTE_SPECIES.indexInRange(i, limit);
28+
var vector = ByteVector.fromMemorySegment(BYTE_SPECIES, memSegment, i, byteBuffer.order(), mask);
29+
30+
var newlines = vector.compare(VectorOperators.EQ, newlineVector).toLong();
31+
var newlineCount = Long.bitCount(newlines);
32+
if (newlineCount != 0) {
33+
var last = Long.SIZE - Long.numberOfLeadingZeros(newlines);
34+
for (int j = Long.numberOfTrailingZeros(newlines); j < last; j++) {
35+
if ((newlines & (1L << j)) != 0) {
36+
lineEnd = i + j;
37+
38+
charSequence.buffer().limit(lineEnd).position(lineStart);
39+
consumer.accept(charSequence);
40+
41+
lineStart = lineEnd + 1;
42+
}
43+
}
44+
}
45+
}
46+
}
47+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package dev.linl33.adventofcode.year2022;
2+
3+
import dev.linl33.adventofcode.lib.solution.ByteBufferAdventSolution;
4+
import dev.linl33.adventofcode.lib.solution.NullBufferedReaderSolution;
5+
import dev.linl33.adventofcode.lib.solution.ResourceIdentifier;
6+
import dev.linl33.adventofcode.lib.util.AdventUtil;
7+
import dev.linl33.adventofcode.lib.util.VectorIoUtil;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
import java.nio.ByteBuffer;
11+
import java.util.ArrayDeque;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
public class Day13 extends AdventSolution2022<Integer, Integer>
16+
implements ByteBufferAdventSolution<Integer, Integer>, NullBufferedReaderSolution<Integer, Integer> {
17+
private static final List<List<Integer>> DIVIDER_A = List.of(List.of(2));
18+
private static final List<List<Integer>> DIVIDER_B = List.of(List.of(6));
19+
20+
public static void main(String[] args) {
21+
new Day13().runAndPrintAll();
22+
}
23+
24+
@Override
25+
public Integer part1(@NotNull ResourceIdentifier identifier) throws Exception {
26+
return ByteBufferAdventSolution.super.part1(identifier);
27+
}
28+
29+
@Override
30+
public Integer part2(@NotNull ResourceIdentifier identifier) throws Exception {
31+
return ByteBufferAdventSolution.super.part2(identifier);
32+
}
33+
34+
@Override
35+
public Integer part1(@NotNull ByteBuffer reader) throws Exception {
36+
var counters = new int[3];
37+
var pairLeft = new List<?>[1];
38+
39+
VectorIoUtil.readLines(reader, line -> {
40+
var i = (counters[0]++) % 3;
41+
42+
if (i == 2) {
43+
return;
44+
}
45+
46+
if (i == 1) {
47+
var parsed = parseLine(line, pairLeft[0].size());
48+
var order = check(pairLeft[0], parsed);
49+
var pairIdx = ++counters[1];
50+
51+
if (order <= 0) {
52+
counters[2] += pairIdx;
53+
}
54+
} else {
55+
pairLeft[0] = parseLine(line, 0);
56+
}
57+
});
58+
59+
return counters[2];
60+
}
61+
62+
@Override
63+
public Integer part2(@NotNull ByteBuffer reader) throws Exception {
64+
var counters = new int[3];
65+
VectorIoUtil.readLines(reader, line -> {
66+
var i = (counters[0]++) % 3;
67+
68+
if (i == 2) {
69+
return;
70+
}
71+
72+
var list = parseLine(line, 1);
73+
if (check(list, DIVIDER_A) < 0) {
74+
counters[1]++;
75+
} else if (check(list, DIVIDER_B) < 0) {
76+
counters[2]++;
77+
}
78+
});
79+
80+
return (counters[1] + 1) * ((counters[1] + 1) + (counters[2] + 1));
81+
}
82+
83+
private static int check(Object left, Object right) {
84+
if (left instanceof Integer leftInt && right instanceof Integer rightInt) {
85+
return leftInt - rightInt;
86+
}
87+
88+
if (left instanceof List<?> leftList && right instanceof List<?> rightList) {
89+
if (leftList.isEmpty()) {
90+
return rightList.isEmpty() ? 0 : -1;
91+
}
92+
93+
var size = Math.min(leftList.size(), rightList.size());
94+
for (int i = 0; i < size; i++) {
95+
var leftItem = leftList.get(i);
96+
var rightItem = rightList.get(i);
97+
98+
var itemCheck = check(leftItem, rightItem);
99+
if (itemCheck != 0) {
100+
return itemCheck;
101+
}
102+
}
103+
104+
return leftList.size() - rightList.size();
105+
}
106+
107+
if (left instanceof Integer leftInt) {
108+
return check(List.of(leftInt), right);
109+
}
110+
111+
if (right instanceof Integer rightInt) {
112+
return check(left, List.of(rightInt));
113+
}
114+
115+
throw new IllegalStateException("Malformed input");
116+
}
117+
118+
private static List<Object> parseLine(CharSequence line, int limit) {
119+
var stack = new ArrayDeque<List<Object>>();
120+
121+
for (int i = 0; i < line.length(); i++) {
122+
var c = line.charAt(i);
123+
124+
if (c == '[') {
125+
stack.push(new ArrayList<>());
126+
continue;
127+
}
128+
129+
if (limit > 0 && stack.size() == 1 && stack.peek().size() >= limit) {
130+
return stack.pop();
131+
}
132+
133+
if (c == ']') {
134+
var l = stack.pop();
135+
if (stack.isEmpty()) {
136+
return l;
137+
} else {
138+
stack.peek().add(l);
139+
}
140+
} else if (c != ',') {
141+
var num = c - '0';
142+
143+
var next = line.charAt(i + 1);
144+
if (next >= '0' && next <= '9') {
145+
i++;
146+
num = 10 * num + (next - '0');
147+
}
148+
149+
stack.peek().add(num);
150+
}
151+
}
152+
153+
throw new IllegalArgumentException("Malformed input");
154+
}
155+
}

0 commit comments

Comments
 (0)