Skip to content

Instantly share code, notes, and snippets.

@SirYwell
Created December 4, 2022 18:30
Show Gist options
  • Save SirYwell/26fe3a1e497bf3095cffdbea28ecba04 to your computer and use it in GitHub Desktop.
Save SirYwell/26fe3a1e497bf3095cffdbea28ecba04 to your computer and use it in GitHub Desktop.
AOC Day 02 Java Vector API solution
package de.sirywell.aoc2022.java.day02;
import jdk.incubator.vector.ByteVector;
import jdk.incubator.vector.ShortVector;
import jdk.incubator.vector.VectorMask;
import jdk.incubator.vector.VectorShuffle;
import jdk.incubator.vector.VectorSpecies;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import static jdk.incubator.vector.VectorOperators.ADD;
import static jdk.incubator.vector.VectorOperators.FIRST_NONZERO;
import static jdk.incubator.vector.VectorOperators.XOR;
public class Day02 {
private static final VectorSpecies<Byte> BYTE_V = ByteVector.SPECIES_PREFERRED;
private static final VectorSpecies<Short> SHORT_V = ShortVector.SPECIES_PREFERRED;
private static final VectorShuffle<Byte> ROTATE_ONE = VectorShuffle.iota(BYTE_V, 1, 1, true);
private static final VectorShuffle<Byte> ROTATE_M_ONE = VectorShuffle.iota(BYTE_V, -1, 1, true);
private static final VectorMask<Byte> SELECT_AT_EVEN = VectorMask.fromLong(BYTE_V, 0x5555555555555555L);
private static final VectorMask<Byte> SELECT_AT_ODD = SELECT_AT_EVEN.not();
public static void main(String[] args) throws IOException {
String s = Files.readString(Path.of("src/main/resources/day02/input.txt"));
byte[] raw = s.replace(" ", "")
.replace("\r", "")
.replace("\n", "").getBytes(StandardCharsets.UTF_8);
int l = raw.length;
int step = BYTE_V.length() << 1;
int bound = l & -step;
ShortVector firstSum = ShortVector.zero(SHORT_V);
ShortVector secondSum = ShortVector.zero(SHORT_V);
int offset;
for (offset = 0; offset < bound; offset += step) {
ByteVector l0 = ByteVector.fromArray(BYTE_V, raw, offset);
ByteVector l1 = ByteVector.fromArray(BYTE_V, raw, offset + BYTE_V.length());
ByteVector as = l0.lanewise(XOR, l0, SELECT_AT_ODD);
ByteVector bs = l0.lanewise(XOR, l0, SELECT_AT_EVEN);
as = as.lanewise(FIRST_NONZERO, l1.rearrange(ROTATE_M_ONE));
bs = bs.rearrange(ROTATE_ONE).lanewise(FIRST_NONZERO, l1);
as = as.sub((byte) 'A');
bs = bs.sub((byte) 'X');
ByteVector first = eval(as, bs);
firstSum = firstSum.add(first.castShape(SHORT_V, 0));
firstSum = firstSum.add(first.castShape(SHORT_V, 1));
bs = modBy3(bs.add(as).add((byte) 2));
ByteVector second = eval(as, bs);
secondSum = secondSum.add(second.castShape(SHORT_V, 0));
secondSum = secondSum.add(second.castShape(SHORT_V, 1));
}
int firstResult = firstSum.reduceLanes(ADD);
int secondResult = secondSum.reduceLanes(ADD);
for (; offset < raw.length; offset += 2) {
int opponent = (raw[offset] - 'A');
int self = (raw[offset + 1] - 'X');
firstResult += (4 - opponent + self) % 3 * 3 + self + 1;
self = (opponent + self + 2) % 3;
secondResult += (4 - opponent + self) % 3 * 3 + self + 1;
}
System.out.println(firstResult);
System.out.println(secondResult);
}
private static ByteVector eval(ByteVector opponent, ByteVector self) {
final byte one = 1;
final byte three = 3;
ByteVector four = ByteVector.broadcast(BYTE_V, 4);
ByteVector beforeMod = four.sub(opponent).add(self);
return modBy3(beforeMod)
.mul(three).add(self).add(one);
}
private static ByteVector modBy3(ByteVector vector) {
final byte three = 3;
return vector.sub(vector.div(three).mul(three));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment