Compare commits
36 Commits
5d73f12e43
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3906d6ef72 | |||
| 1d745a0855 | |||
| 3550f65914 | |||
| 20f20a3179 | |||
| eff95027de | |||
| 76e670770e | |||
| e014b32ab4 | |||
| ed3c7f3a04 | |||
| 73235b3e44 | |||
| 118b56e5f3 | |||
| b5e8ea0a3b | |||
| 57f4a97627 | |||
| 20e2555470 | |||
| 998c523971 | |||
| 7de77107e6 | |||
| 5bb873bcc5 | |||
| c3e8e6320e | |||
| 81a488aaee | |||
| 5c94aed258 | |||
| 97334d34eb | |||
| 399d894c68 | |||
| 782fccc572 | |||
| 811a6a0af0 | |||
| b9a8e7585b | |||
| 15b11a191d | |||
| 3e09eee5b7 | |||
| 322f8eb45a | |||
| ccfcf5a259 | |||
| ae327a4928 | |||
| 4fef41464e | |||
| 4a90257257 | |||
| 522618d106 | |||
| 0ad5dac997 | |||
| 7a871771bb | |||
| c11231307f | |||
| e72f71c1bf |
@@ -0,0 +1,14 @@
|
|||||||
|
plugins {
|
||||||
|
id("java-convention")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":utils"))
|
||||||
|
|
||||||
|
annotationProcessor(Libs.Micronaut.processor)
|
||||||
|
|
||||||
|
implementation(Libs.eclipseCollections)
|
||||||
|
|
||||||
|
testImplementation(Libs.Jmh.core)
|
||||||
|
testAnnotationProcessor(Libs.Jmh.processor)
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package be.vandewalleh.aoc;
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.factory.Days;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Lines;
|
||||||
|
|
||||||
|
@Day(1)
|
||||||
|
public class Day01 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var day = Days.createDay(Day01.class);
|
||||||
|
System.out.println(day.part1());
|
||||||
|
System.out.println(day.part2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int[] input;
|
||||||
|
|
||||||
|
public Day01(@Lines int[] input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int fuel(int mass) {
|
||||||
|
return (mass / 3) - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int part1() {
|
||||||
|
var total = 0;
|
||||||
|
for (var mass : input) {
|
||||||
|
total += fuel(mass);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int part2() {
|
||||||
|
var total = 0;
|
||||||
|
for (var mass : input) {
|
||||||
|
int fuel = fuel(mass);
|
||||||
|
total += fuel;
|
||||||
|
while (true) {
|
||||||
|
fuel = fuel(fuel);
|
||||||
|
if (fuel <= 0) break;
|
||||||
|
total += fuel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package be.vandewalleh.aoc;
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.intcode.IntCodeInterpreter;
|
||||||
|
import be.vandewalleh.aoc.utils.factory.Days;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Csv;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day;
|
||||||
|
|
||||||
|
@Day(2)
|
||||||
|
public class Day02 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var day = Days.createDay(Day02.class);
|
||||||
|
System.out.println(day.part1());
|
||||||
|
System.out.println(day.part2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int[] input;
|
||||||
|
|
||||||
|
public Day02(@Csv int[] input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long runInterpreterWith(int noun, int verb) {
|
||||||
|
var interpreter = new IntCodeInterpreter(input);
|
||||||
|
interpreter.setNoun(noun);
|
||||||
|
interpreter.setVerb(verb);
|
||||||
|
interpreter.run();
|
||||||
|
return interpreter.getOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long part1() {
|
||||||
|
return runInterpreterWith(12, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int part2() {
|
||||||
|
for (var noun = 0; noun < 99; noun++) {
|
||||||
|
for (var verb = 0; verb < 99; verb++) {
|
||||||
|
if (runInterpreterWith(noun, verb) == 19690720L) return 100 * noun + verb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package be.vandewalleh.aoc;
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.geometry.Direction2D;
|
||||||
|
import be.vandewalleh.aoc.geometry.Point2D;
|
||||||
|
import be.vandewalleh.aoc.utils.factory.Days;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Lines;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Day(3)
|
||||||
|
public class Day03 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var day = Days.createDay(Day03.class);
|
||||||
|
System.out.println(day.part1());
|
||||||
|
System.out.println(day.part2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String[] wireA;
|
||||||
|
private final String[] wireB;
|
||||||
|
|
||||||
|
public Day03(@Lines List<String> input) {
|
||||||
|
this.wireA = input.get(0).split(",");
|
||||||
|
this.wireB = input.get(1).split(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Point2D> path(String[] wire) {
|
||||||
|
var points = new ArrayList<Point2D>();
|
||||||
|
var point = Point2D.origin;
|
||||||
|
for (var section : wire) {
|
||||||
|
var direction = Direction2D.from(section.charAt(0));
|
||||||
|
var count = Integer.parseInt(section.substring(1));
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
point = point.translate(direction.point);
|
||||||
|
points.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int part1() {
|
||||||
|
var pathA = path(wireA);
|
||||||
|
var pathB = path(wireB);
|
||||||
|
|
||||||
|
var intersections = new HashSet<>(pathA);
|
||||||
|
intersections.retainAll(pathB);
|
||||||
|
|
||||||
|
return intersections.stream().mapToInt(Point2D::manhattanDistance).min().orElse(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int part2() {
|
||||||
|
var pathA = path(wireA);
|
||||||
|
var pathB = path(wireB);
|
||||||
|
|
||||||
|
var intersections = new HashSet<>(pathA);
|
||||||
|
intersections.retainAll(pathB);
|
||||||
|
|
||||||
|
return intersections.stream().mapToInt(p -> pathA.indexOf(p) + pathB.indexOf(p) + 2).min().orElse(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package be.vandewalleh.aoc;
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.factory.Days;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Text;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@Day(4)
|
||||||
|
public class Day04 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var day = Days.createDay(Day04.class);
|
||||||
|
System.out.println(day.part1());
|
||||||
|
System.out.println(day.part2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int min;
|
||||||
|
private final int max;
|
||||||
|
|
||||||
|
public Day04(@Text String input) {
|
||||||
|
var spl = input.split("-", 2);
|
||||||
|
min = Integer.parseInt(spl[0]);
|
||||||
|
max = Integer.parseInt(spl[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNotDecreasing(int[] ints) {
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
int a = ints[i], b = ints[i + 1];
|
||||||
|
if (b < a) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPair(int[] ints) {
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
int a = ints[i], b = ints[i + 1];
|
||||||
|
if (a == b) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasGroup(int[] ints) {
|
||||||
|
var occurrences = new int[10];
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
int a = ints[i], b = ints[i + 1];
|
||||||
|
if (a == b) occurrences[a]++;
|
||||||
|
}
|
||||||
|
return Arrays.stream(occurrences).anyMatch(e -> e == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream<int[]> intStream() {
|
||||||
|
return IntStream.rangeClosed(min, max)
|
||||||
|
.mapToObj(String::valueOf)
|
||||||
|
.map(String::toCharArray)
|
||||||
|
.map(e -> {
|
||||||
|
var ints = new int[6];
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
ints[i] = Integer.parseInt(String.valueOf(e[i]));
|
||||||
|
}
|
||||||
|
return ints;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private long part1() {
|
||||||
|
return intStream()
|
||||||
|
.filter(this::isNotDecreasing)
|
||||||
|
.filter(this::hasPair)
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long part2() {
|
||||||
|
return intStream()
|
||||||
|
.filter(this::isNotDecreasing)
|
||||||
|
.filter(this::hasGroup)
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package be.vandewalleh.aoc;
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.intcode.IntCodeInterpreter;
|
||||||
|
import be.vandewalleh.aoc.utils.factory.Days;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Csv;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day;
|
||||||
|
|
||||||
|
@Day(5)
|
||||||
|
public class Day05 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var day = Days.createDay(Day05.class);
|
||||||
|
System.out.println(day.part1());
|
||||||
|
System.out.println(day.part2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int[] input;
|
||||||
|
|
||||||
|
public Day05(@Csv int[] input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long part1() {
|
||||||
|
var interpreter = new IntCodeInterpreter(input);
|
||||||
|
interpreter.setInput(1);
|
||||||
|
interpreter.run();
|
||||||
|
return interpreter.getOutputs().peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long part2() {
|
||||||
|
var interpreter = new IntCodeInterpreter(input);
|
||||||
|
interpreter.setInput(5);
|
||||||
|
interpreter.run();
|
||||||
|
return interpreter.getOutputs().peek();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package be.vandewalleh.aoc;
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.factory.Days;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day;
|
||||||
|
import be.vandewalleh.aoc.utils.input.Lines;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Day(6)
|
||||||
|
public class Day06 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var day = Days.createDay(Day06.class);
|
||||||
|
System.out.println(day.part1());
|
||||||
|
System.out.println(day.part2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<String> input;
|
||||||
|
|
||||||
|
public Day06(@Lines List<String> input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<String, String> reverseOrbits = new HashMap<>();
|
||||||
|
|
||||||
|
private int countDirectOrbits() {
|
||||||
|
return reverseOrbits.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countIndirectOrbits() {
|
||||||
|
var count = 0;
|
||||||
|
for (var key : reverseOrbits.keySet()) {
|
||||||
|
count += countIndirectOrbits(key);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countIndirectOrbits(String key) {
|
||||||
|
var count = 0;
|
||||||
|
var currentKey = reverseOrbits.get(key);
|
||||||
|
while (currentKey != null) {
|
||||||
|
currentKey = reverseOrbits.get(currentKey);
|
||||||
|
if (currentKey != null) count++;
|
||||||
|
else return count;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> pathToCom(String key) {
|
||||||
|
var path = new ArrayList<String>();
|
||||||
|
var currentKey = reverseOrbits.get(key);
|
||||||
|
path.add(currentKey);
|
||||||
|
while (currentKey != null) {
|
||||||
|
currentKey = reverseOrbits.get(currentKey);
|
||||||
|
if (currentKey == null) return path;
|
||||||
|
else path.add(currentKey);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int part1() {
|
||||||
|
for (var line : input) {
|
||||||
|
var split = line.split("\\)");
|
||||||
|
reverseOrbits.put(split[1], split[0]);
|
||||||
|
}
|
||||||
|
return countDirectOrbits() + countIndirectOrbits();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int part2() {
|
||||||
|
var sanPath = pathToCom("SAN");
|
||||||
|
var youPath = pathToCom("YOU");
|
||||||
|
|
||||||
|
var common = new LinkedHashSet<>(sanPath);
|
||||||
|
common.retainAll(youPath);
|
||||||
|
|
||||||
|
String closestCommon = (String) common.toArray()[0];
|
||||||
|
return sanPath.indexOf(closestCommon) + youPath.indexOf(closestCommon);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package be.vandewalleh.aoc.geometry;
|
||||||
|
|
||||||
|
public enum Direction2D {
|
||||||
|
Up(0, -1), Down(0, 1), Right(1, 0), Left(-1, 0);
|
||||||
|
|
||||||
|
public final Point2D point;
|
||||||
|
|
||||||
|
Direction2D(int x, int y) {
|
||||||
|
this.point = new Point2D(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Direction2D from(char direction) {
|
||||||
|
switch (direction) {
|
||||||
|
case 'U' -> {
|
||||||
|
return Direction2D.Up;
|
||||||
|
}
|
||||||
|
case 'D' -> {
|
||||||
|
return Direction2D.Down;
|
||||||
|
}
|
||||||
|
case 'R' -> {
|
||||||
|
return Direction2D.Right;
|
||||||
|
}
|
||||||
|
case 'L' -> {
|
||||||
|
return Direction2D.Left;
|
||||||
|
}
|
||||||
|
default -> throw new IllegalArgumentException("Unexpected value: " + direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package be.vandewalleh.aoc.geometry;
|
||||||
|
|
||||||
|
public record Point2D(int x, int y) {
|
||||||
|
public static Point2D origin = new Point2D(0, 0);
|
||||||
|
|
||||||
|
public int manhattanDistance() {
|
||||||
|
return Math.abs(x) + Math.abs(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point2D translate(Point2D other) {
|
||||||
|
return new Point2D(this.x + other.x, this.y + other.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package be.vandewalleh.aoc.intcode;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Deque;
|
||||||
|
|
||||||
|
public class IntCodeInterpreter {
|
||||||
|
private final Deque<Long> outputs = new ArrayDeque<>();
|
||||||
|
private final long[] memory;
|
||||||
|
private long input;
|
||||||
|
|
||||||
|
public IntCodeInterpreter(int[] memory) {
|
||||||
|
this.memory = Arrays.stream(memory).asLongStream().toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoun(long noun) {
|
||||||
|
memory[1] = noun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVerb(long verb) {
|
||||||
|
memory[2] = verb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInput(long input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getOutput() {
|
||||||
|
return memory[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// private ?
|
||||||
|
public Deque<Long> getOutputs() {
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long readArgument(Mode mode, long param) {
|
||||||
|
switch (mode) {
|
||||||
|
case Positional -> {
|
||||||
|
return memory[(int) param];
|
||||||
|
}
|
||||||
|
case Immediate -> {
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
default -> throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeArgument(long param, long value) {
|
||||||
|
memory[(int) param] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mode[] modes(long instruction) {
|
||||||
|
var str = String.format("%5d", instruction).replace(' ', '0');
|
||||||
|
return new Mode[]{
|
||||||
|
Mode.of(str.charAt(2)),
|
||||||
|
Mode.of(str.charAt(1)),
|
||||||
|
Mode.of(str.charAt(0))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
var pointer = 0;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
while (true) {
|
||||||
|
var jumped = false;
|
||||||
|
var instruction = memory[pointer];
|
||||||
|
var opCode = OpCode.from(((int) instruction) % 100);
|
||||||
|
var args = Arrays.copyOfRange(memory, pointer + 1, pointer + opCode.params + 1);
|
||||||
|
var modes = modes(instruction);
|
||||||
|
switch (opCode) {
|
||||||
|
case Add -> {
|
||||||
|
var value = readArgument(modes[0], args[0]) + readArgument(modes[1], args[1]);
|
||||||
|
writeArgument(args[2], value);
|
||||||
|
}
|
||||||
|
case Multiply -> {
|
||||||
|
var value = readArgument(modes[0], args[0]) * readArgument(modes[1], args[1]);
|
||||||
|
writeArgument(args[2], value);
|
||||||
|
}
|
||||||
|
case In -> {
|
||||||
|
writeArgument(args[0], input);
|
||||||
|
}
|
||||||
|
case Out -> {
|
||||||
|
outputs.push(readArgument(modes[0], args[0]));
|
||||||
|
}
|
||||||
|
case JumpIfTrue -> {
|
||||||
|
if (readArgument(modes[0], args[0]) != 0) {
|
||||||
|
pointer = (int) readArgument(modes[1], args[1]);
|
||||||
|
jumped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case JumpIfFalse -> {
|
||||||
|
if (readArgument(modes[0], args[0]) == 0) {
|
||||||
|
pointer = (int) readArgument(modes[1], args[1]);
|
||||||
|
jumped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case LessThan -> {
|
||||||
|
var value = readArgument(modes[0], args[0]) < readArgument(modes[1], args[1]) ? 1 : 0;
|
||||||
|
writeArgument(args[2], value);
|
||||||
|
}
|
||||||
|
case Equals -> {
|
||||||
|
var value = readArgument(modes[0], args[0]) == readArgument(modes[1], args[1]) ? 1 : 0;
|
||||||
|
writeArgument(args[2], value);
|
||||||
|
}
|
||||||
|
case Halt -> {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!jumped) pointer += opCode.params + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package be.vandewalleh.aoc.intcode;
|
||||||
|
|
||||||
|
public enum Mode {
|
||||||
|
Positional, Immediate;
|
||||||
|
|
||||||
|
public static Mode of(char representation) {
|
||||||
|
if (representation == '0') return Mode.Positional;
|
||||||
|
else if (representation == '1') return Mode.Immediate;
|
||||||
|
else throw new IllegalArgumentException("Unsupported Mode " + representation);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package be.vandewalleh.aoc.intcode;
|
||||||
|
|
||||||
|
public enum OpCode {
|
||||||
|
Add(1, 3),
|
||||||
|
Multiply(2, 3),
|
||||||
|
Halt(99, 0),
|
||||||
|
In(3, 1),
|
||||||
|
Out(4, 1),
|
||||||
|
JumpIfTrue(5, 2),
|
||||||
|
JumpIfFalse(6, 2),
|
||||||
|
LessThan(7, 3),
|
||||||
|
Equals(8, 3),
|
||||||
|
;
|
||||||
|
|
||||||
|
public final int value;
|
||||||
|
public final int params;
|
||||||
|
|
||||||
|
OpCode(int value, int params) {
|
||||||
|
this.value = value;
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OpCode from(int value) {
|
||||||
|
for (OpCode opCode : OpCode.values()) {
|
||||||
|
if (opCode.value == value) return opCode;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unsupported OpCode " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
132791
|
||||||
|
78272
|
||||||
|
114679
|
||||||
|
60602
|
||||||
|
59038
|
||||||
|
69747
|
||||||
|
61672
|
||||||
|
147972
|
||||||
|
92618
|
||||||
|
70186
|
||||||
|
125826
|
||||||
|
61803
|
||||||
|
78112
|
||||||
|
124864
|
||||||
|
58441
|
||||||
|
113062
|
||||||
|
105389
|
||||||
|
125983
|
||||||
|
90716
|
||||||
|
75544
|
||||||
|
148451
|
||||||
|
73739
|
||||||
|
127762
|
||||||
|
146660
|
||||||
|
128747
|
||||||
|
148129
|
||||||
|
138635
|
||||||
|
80095
|
||||||
|
60241
|
||||||
|
145455
|
||||||
|
98730
|
||||||
|
59139
|
||||||
|
146828
|
||||||
|
113550
|
||||||
|
91682
|
||||||
|
107415
|
||||||
|
129207
|
||||||
|
147635
|
||||||
|
104583
|
||||||
|
102245
|
||||||
|
73446
|
||||||
|
148657
|
||||||
|
96364
|
||||||
|
52033
|
||||||
|
69964
|
||||||
|
63609
|
||||||
|
98207
|
||||||
|
73401
|
||||||
|
65511
|
||||||
|
115034
|
||||||
|
126179
|
||||||
|
96664
|
||||||
|
85394
|
||||||
|
128472
|
||||||
|
79017
|
||||||
|
93222
|
||||||
|
55267
|
||||||
|
102446
|
||||||
|
133150
|
||||||
|
148985
|
||||||
|
95325
|
||||||
|
57713
|
||||||
|
77370
|
||||||
|
60879
|
||||||
|
111977
|
||||||
|
99362
|
||||||
|
91581
|
||||||
|
55201
|
||||||
|
137670
|
||||||
|
127159
|
||||||
|
128324
|
||||||
|
77217
|
||||||
|
86378
|
||||||
|
112847
|
||||||
|
108265
|
||||||
|
80355
|
||||||
|
75650
|
||||||
|
106222
|
||||||
|
67793
|
||||||
|
113891
|
||||||
|
74508
|
||||||
|
139463
|
||||||
|
69972
|
||||||
|
122753
|
||||||
|
135854
|
||||||
|
127770
|
||||||
|
101085
|
||||||
|
98304
|
||||||
|
61451
|
||||||
|
146719
|
||||||
|
61225
|
||||||
|
60468
|
||||||
|
83613
|
||||||
|
137436
|
||||||
|
126303
|
||||||
|
78759
|
||||||
|
70081
|
||||||
|
110671
|
||||||
|
113234
|
||||||
|
111563
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,6,1,19,1,5,19,23,2,6,23,27,1,27,5,31,2,9,31,35,1,5,35,39,2,6,39,43,2,6,43,47,1,5,47,51,2,9,51,55,1,5,55,59,1,10,59,63,1,63,6,67,1,9,67,71,1,71,6,75,1,75,13,79,2,79,13,83,2,9,83,87,1,87,5,91,1,9,91,95,2,10,95,99,1,5,99,103,1,103,9,107,1,13,107,111,2,111,10,115,1,115,5,119,2,13,119,123,1,9,123,127,1,5,127,131,2,131,6,135,1,135,5,139,1,139,6,143,1,143,6,147,1,2,147,151,1,151,5,0,99,2,14,0,0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
R1000,U371,R195,U136,R804,U805,L450,U211,R768,U768,L548,U354,L736,U431,L152,U658,L670,D262,L277,U136,L290,U939,R501,U550,L931,D839,R335,D492,L25,U80,R878,U355,R653,U186,R423,D485,L793,D259,L739,U679,R508,D269,R432,D761,R97,D461,L675,U958,L58,U348,L719,D271,R144,U849,R384,U72,L84,U493,R947,U30,L356,D442,R327,U646,R825,U718,L329,D173,L949,D345,L971,D830,L93,U506,R245,D376,R322,D105,L604,D60,R298,D959,L165,D423,R180,D527,R956,D944,R785,U641,L794,D182,R975,D719,L166,U974,L224,U243,L666,U706,R796,D600,L856,D913,L988,D993,L259,U351,R487,D424,L335,U910,L437,D180,R621,D3,R878,D188,R254,D393,L727,U829,R352,U958,L327,D158,L854,D17,R143,D454,R889,D265,L345,U784,R35,D129,R77,U117,R951,D980,L866,U646,R242,D603,L562,U727,L496,U328,L380,D504,R644,U803,L530,D546,R328,D373,L489,U454,R74,D908,R366,U94,R604,D482,L573,D27,R943,U497,L782,D267,L391,U49,R528,D58,R155,D529,R227,D998,R558,D891,R224,U843,R512,U34,R92,U404,R752,U946,L338,D880,L513,D28,L856,D444,L187,U532,L187,U669,L306,U259,R287,D442,R478,U576,R702,U336,L305,U701,L754,D277,R760,D863,L717,U196,L221,U101,L334,D156,L961,D810,L67,D716,L457,D44,L505,D724,R716,D660,L36,D338,R54,U424,R730,U18,L65,D133,R149,U374,R356,D989,R519,U593,L444,D270,R328,U167,L748,D797,L434,U751,R444,D71,R158,D530,L630,U147,R909,D994,L957,U521,L644,D579,R673,U191,R935,U237,R600,D321,L671,U961,L884,U378,R534,D46,R275,U845,R571,U245,L507,U273,R995,U408,L14,D799,L955,D534,R579,D94,R705,D391,R469,D381,R620,U162,R907,D826,R824,U167,L734,U922,L484
|
||||||
|
L1007,D620,R853,U77,L13,U473,L253,D410,R897,U464,L862,U281,L650,D470,R87,D204,L896,U670,L864,D950,L75,D320,R901,D785,L653,D225,L857,U616,L143,U940,L664,U131,L547,D745,R636,U569,L50,U454,R288,D254,L36,U377,L609,U929,L714,U85,L939,U923,L566,D280,R243,U948,R447,D7,R908,D151,R824,D432,R34,D81,L458,U745,L420,D982,L625,U910,L729,D274,R910,U322,L984,D88,L700,D349,L932,U510,R625,U88,L252,U785,L378,D101,R299,U66,L476,U696,R236,D46,R590,U157,R461,U305,L269,D487,L676,U467,R319,D524,R75,U65,L478,U861,L238,D716,R888,D12,L184,D578,R266,D226,L656,D172,L752,U124,L831,U810,L663,U538,R417,D770,L359,U1,R12,U791,L332,U272,R574,D942,L857,U447,R310,U342,L713,D258,R590,D585,R129,D115,R832,D967,R981,D159,R864,U423,R268,U519,L52,D493,R445,D657,R885,U166,R155,D264,R51,D632,R525,D875,R617,U898,L556,D386,L143,U278,L767,D389,R821,U869,R286,D90,R289,U54,R15,D764,R46,D674,R983,U49,R959,U779,R958,D247,R483,U156,L18,U12,L178,U540,L499,U487,L544,D336,R814,U267,R145,D135,L920,D902,L933,D507,L997,U361,L577,U425,L773,D782,R117,U851,R998,U503,R902,U781,L161,U98,L653,U633,L91,U629,L138,D19,R147,D756,R364,D529,L764,U913,L118,U856,R774,D621,R151,U154,R737,D960,R86,U458,R991,D481,R560,D858,R223,D6,R931,D301,R552,D797,R284,U368,L967,D686,R940,U410,R137,D156,L6,U643,L445,D999,R888,D277,L852,U210,L777,D36,R103,D652,R120,D67,L642,D527,R913,D858,R69,D433,R864,U75,L531,U456,L664,D452,R801,U851,L824,D278,L526,U133,R200,U768,R15,U393,R982,U287,L38,D114,R86,U299,L819,D891,R379,D601,L244
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
272091-815432
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3,225,1,225,6,6,1100,1,238,225,104,0,1101,11,91,225,1002,121,77,224,101,-6314,224,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,223,1102,74,62,225,1102,82,7,224,1001,224,-574,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,28,67,225,1102,42,15,225,2,196,96,224,101,-4446,224,224,4,224,102,8,223,223,101,6,224,224,1,223,224,223,1101,86,57,225,1,148,69,224,1001,224,-77,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1101,82,83,225,101,87,14,224,1001,224,-178,224,4,224,1002,223,8,223,101,7,224,224,1,223,224,223,1101,38,35,225,102,31,65,224,1001,224,-868,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,57,27,224,1001,224,-84,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,61,78,225,1001,40,27,224,101,-89,224,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,677,226,224,1002,223,2,223,1006,224,329,101,1,223,223,8,226,677,224,102,2,223,223,1005,224,344,101,1,223,223,1107,226,677,224,102,2,223,223,1006,224,359,101,1,223,223,1007,226,226,224,102,2,223,223,1006,224,374,101,1,223,223,7,677,677,224,102,2,223,223,1005,224,389,1001,223,1,223,108,677,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,226,226,224,102,2,223,223,1005,224,419,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,434,1001,223,1,223,1108,677,677,224,102,2,223,223,1006,224,449,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,464,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,479,101,1,223,223,1007,226,677,224,1002,223,2,223,1006,224,494,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,509,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,524,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,539,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,554,1001,223,1,223,7,677,226,224,102,2,223,223,1006,224,569,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,584,101,1,223,223,1107,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,614,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,629,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,644,1001,223,1,223,108,226,226,224,102,2,223,223,1005,224,659,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
id("kotlin-convention")
|
||||||
|
kotlin("kapt")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":utils"))
|
||||||
|
|
||||||
|
kapt(Libs.Micronaut.processor)
|
||||||
|
|
||||||
|
implementation(Libs.Slf4J.api)
|
||||||
|
runtimeOnly(Libs.Slf4J.simple)
|
||||||
|
|
||||||
|
implementation(Libs.eclipseCollections)
|
||||||
|
|
||||||
|
testImplementation(Libs.Jmh.core)
|
||||||
|
kaptTest(Libs.Jmh.processor)
|
||||||
|
}
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
@Day(1)
|
@Day(1)
|
||||||
class Day01(@Lines input: Input<IntArray>) {
|
class Day01(@Lines val items: IntArray) {
|
||||||
private val items = input.value
|
|
||||||
|
|
||||||
fun part1(): Int? {
|
fun part1(): Int? {
|
||||||
items.forEach { a ->
|
items.forEach { a ->
|
||||||
items.forEach { b ->
|
items.forEach { b ->
|
||||||
@@ -31,7 +27,3 @@ class Day01(@Lines input: Input<IntArray>) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day01>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
data class PasswordEntry(val range: IntRange, val letter: Char, val password: String)
|
|
||||||
|
|
||||||
@Day(2)
|
@Day(2)
|
||||||
class Day02(@Lines input: Input<List<String>>) {
|
class Day02(@Lines input: List<String>) {
|
||||||
|
private data class PasswordEntry(val range: IntRange, val letter: Char, val password: String)
|
||||||
|
|
||||||
private val regex = "^(\\d+)-(\\d+) ([a-z]): (.*)$".toRegex()
|
private val regex = "^(\\d+)-(\\d+) ([a-z]): (.*)$".toRegex()
|
||||||
|
|
||||||
private val passwords = input.value.map {
|
private val passwords = input.map {
|
||||||
val (_, min, max, letter, password) = regex.find(it)!!.groupValues
|
val (_, min, max, letter, password) = regex.find(it)!!.groupValues
|
||||||
PasswordEntry(min.toInt()..max.toInt(), letter[0], password)
|
PasswordEntry(min.toInt()..max.toInt(), letter[0], password)
|
||||||
}
|
}
|
||||||
@@ -22,8 +20,3 @@ class Day02(@Lines input: Input<List<String>>) {
|
|||||||
(pwd[range.first - 1] == letter) xor (pwd[range.last - 1] == letter)
|
(pwd[range.first - 1] == letter) xor (pwd[range.last - 1] == letter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day02>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
data class Slope(val x: Int, val y: Int)
|
|
||||||
|
|
||||||
@Day(3)
|
@Day(3)
|
||||||
class Day03(@Lines val input: Input<List<String>>) {
|
class Day03(@Lines val input: List<String>) {
|
||||||
|
private data class Slope(val x: Int, val y: Int)
|
||||||
|
|
||||||
fun part1(slope: Slope = Slope(x = 3, y = 1)): Int {
|
private fun findSlope(slope: Slope): Int {
|
||||||
val grid = input.value
|
val grid = input
|
||||||
var trees = 0
|
var trees = 0
|
||||||
var x = 0
|
var x = 0
|
||||||
var y = 0
|
var y = 0
|
||||||
@@ -28,6 +25,8 @@ class Day03(@Lines val input: Input<List<String>>) {
|
|||||||
return trees
|
return trees
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun part1() = findSlope(Slope(x = 3, y = 1))
|
||||||
|
|
||||||
fun part2(): Long = listOf(
|
fun part2(): Long = listOf(
|
||||||
Slope(x = 1, y = 1),
|
Slope(x = 1, y = 1),
|
||||||
Slope(x = 3, y = 1),
|
Slope(x = 3, y = 1),
|
||||||
@@ -35,11 +34,6 @@ class Day03(@Lines val input: Input<List<String>>) {
|
|||||||
Slope(x = 7, y = 1),
|
Slope(x = 7, y = 1),
|
||||||
Slope(x = 1, y = 2),
|
Slope(x = 1, y = 2),
|
||||||
)
|
)
|
||||||
.map { part1(it).toLong() }
|
.map { findSlope(it).toLong() }
|
||||||
.reduce { acc, trees -> acc * trees }
|
.reduce { acc, trees -> acc * trees }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day03>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Text
|
import be.vandewalleh.aoc.utils.input.Text
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
typealias Entry = Pair<String, String>
|
private typealias Entry = Pair<String, String>
|
||||||
typealias Entries = List<Entry>
|
private typealias Entries = List<Entry>
|
||||||
|
|
||||||
@Day(4)
|
@Day(4)
|
||||||
class Day04(@Text val input: Input<String>) {
|
class Day04(@Text val input: String) {
|
||||||
|
|
||||||
val entries = input.value.split("\n\n").map {
|
val entries = input.split("\n\n").map {
|
||||||
it.split(" ", "\n").map { it.split(":").let { (k, v) -> k to v } }
|
it.split(" ", "\n").map { it.split(":").let { (k, v) -> k to v } }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,8 +40,3 @@ class Day04(@Text val input: Input<String>) {
|
|||||||
|
|
||||||
fun part2() = entries.count { it.hasRequiredKeys() && it.all { it.isValid() } }
|
fun part2() = entries.count { it.hasRequiredKeys() && it.all { it.isValid() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day04>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
@Day(5)
|
@Day(5)
|
||||||
class Day05(@Lines val input: Input<List<String>>) {
|
class Day05(@Lines val input: List<String>) {
|
||||||
|
|
||||||
private val ids = input.value.map {
|
private val ids = input.map {
|
||||||
it.replace("F", "0")
|
it.replace("F", "0")
|
||||||
.replace("B", "1")
|
.replace("B", "1")
|
||||||
.replace("L", "0")
|
.replace("L", "0")
|
||||||
@@ -22,8 +20,3 @@ class Day05(@Lines val input: Input<List<String>>) {
|
|||||||
.find { (a, b) -> b - a > 1 }!!
|
.find { (a, b) -> b - a > 1 }!!
|
||||||
.first() + 1
|
.first() + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day05>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Text
|
import be.vandewalleh.aoc.utils.input.Text
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.impl.factory.primitive.CharBags
|
import org.eclipse.collections.impl.factory.primitive.CharBags
|
||||||
|
|
||||||
@Day(6)
|
@Day(6)
|
||||||
class Day06(@Text val input: Input<String>) {
|
class Day06(@Text val input: String) {
|
||||||
|
|
||||||
private val groups = input.value.split("\n\n")
|
private val groups = input.split("\n\n")
|
||||||
|
|
||||||
fun part1() = groups.sumBy { it.replace("\n", "").toCharArray().toSet().size }
|
fun part1() = groups.sumBy { it.replace("\n", "").toCharArray().toSet().size }
|
||||||
|
|
||||||
@@ -23,8 +21,3 @@ class Day06(@Text val input: Input<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day06>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.api.factory.Stacks
|
import org.eclipse.collections.api.factory.Stacks
|
||||||
import org.eclipse.collections.api.multimap.list.ImmutableListMultimap
|
import org.eclipse.collections.api.multimap.list.ImmutableListMultimap
|
||||||
import org.eclipse.collections.api.stack.MutableStack
|
import org.eclipse.collections.api.stack.MutableStack
|
||||||
import org.eclipse.collections.impl.factory.Multimaps
|
import org.eclipse.collections.impl.factory.Multimaps
|
||||||
|
|
||||||
data class Bag(val count: Int, val color: String)
|
|
||||||
|
|
||||||
@Day(7)
|
@Day(7)
|
||||||
class Day07(@Lines val input: Input<List<String>>) {
|
class Day07(@Lines val input: List<String>) {
|
||||||
|
|
||||||
|
private data class Bag(val count: Int, val color: String)
|
||||||
|
|
||||||
private val map: ImmutableListMultimap<String, Bag>
|
private val map: ImmutableListMultimap<String, Bag>
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ class Day07(@Lines val input: Input<List<String>>) {
|
|||||||
val colorRegex = "^(\\w+ \\w+)".toRegex()
|
val colorRegex = "^(\\w+ \\w+)".toRegex()
|
||||||
val requirementRegex = "(\\d+) (\\w+ \\w+) bag".toRegex()
|
val requirementRegex = "(\\d+) (\\w+ \\w+) bag".toRegex()
|
||||||
|
|
||||||
for (line in input.value) {
|
for (line in input) {
|
||||||
val outerColor = colorRegex.find(line)!!.groupValues[1]
|
val outerColor = colorRegex.find(line)!!.groupValues[1]
|
||||||
for (match in requirementRegex.findAll(line)) {
|
for (match in requirementRegex.findAll(line)) {
|
||||||
val (_, count, color) = match.groupValues
|
val (_, count, color) = match.groupValues
|
||||||
@@ -50,8 +48,3 @@ class Day07(@Lines val input: Input<List<String>>) {
|
|||||||
fun part2() = bagSequence("shiny gold").sumBy { it.count }
|
fun part2() = bagSequence("shiny gold").sumBy { it.count }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day07>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,24 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.impl.factory.primitive.IntLists
|
import org.eclipse.collections.impl.factory.primitive.IntLists
|
||||||
import org.eclipse.collections.impl.factory.primitive.IntSets
|
import org.eclipse.collections.impl.factory.primitive.IntSets
|
||||||
|
|
||||||
@Day(8)
|
@Day(8)
|
||||||
class Day08(@Lines val input: Input<List<String>>) {
|
class Day08(@Lines val input: List<String>) {
|
||||||
|
|
||||||
private val instructions = input.value.map {
|
private val instructions = input.map {
|
||||||
val words = it.split(" ")
|
val words = it.split(" ")
|
||||||
Instruction(Operation.valueOf(words[0].capitalize()), words[1].toInt())
|
Instruction(Operation.valueOf(words[0].capitalize()), words[1].toInt())
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
|
||||||
fun part1() = run(instructions)
|
fun part1() = run(instructions).let {
|
||||||
|
when (it) {
|
||||||
|
is VmResult.Looped -> it.acc
|
||||||
|
is VmResult.Terminated -> it.acc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun run(instructions: Array<Instruction>): VmResult {
|
private fun run(instructions: Array<Instruction>): VmResult {
|
||||||
var acc = 0
|
var acc = 0
|
||||||
@@ -41,7 +44,7 @@ class Day08(@Lines val input: Input<List<String>>) {
|
|||||||
return VmResult.Looped(acc)
|
return VmResult.Looped(acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun part2(): VmResult {
|
fun part2(): Int {
|
||||||
val possibleMutations = IntLists.mutable.empty()
|
val possibleMutations = IntLists.mutable.empty()
|
||||||
instructions.forEachIndexed { i, e ->
|
instructions.forEachIndexed { i, e ->
|
||||||
if (e.operation == Operation.Jmp || e.operation == Operation.Nop) possibleMutations.add(i)
|
if (e.operation == Operation.Jmp || e.operation == Operation.Nop) possibleMutations.add(i)
|
||||||
@@ -54,7 +57,7 @@ class Day08(@Lines val input: Input<List<String>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val res = run(copy)
|
val res = run(copy)
|
||||||
if (res is VmResult.Terminated) return res
|
if (res is VmResult.Terminated) return res.acc
|
||||||
}
|
}
|
||||||
|
|
||||||
error("No result found")
|
error("No result found")
|
||||||
@@ -62,17 +65,11 @@ class Day08(@Lines val input: Input<List<String>>) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Operation { Acc, Jmp, Nop }
|
private enum class Operation { Acc, Jmp, Nop }
|
||||||
|
|
||||||
data class Instruction(val operation: Operation, val argument: Int)
|
private data class Instruction(val operation: Operation, val argument: Int)
|
||||||
|
|
||||||
sealed class VmResult {
|
private sealed class VmResult {
|
||||||
data class Looped(val acc: Int) : VmResult()
|
data class Looped(val acc: Int) : VmResult()
|
||||||
data class Terminated(val acc: Int) : VmResult()
|
data class Terminated(val acc: Int) : VmResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
|
||||||
val day = createDay<Day08>()
|
|
||||||
println(day.part1())
|
|
||||||
println(day.part2())
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,16 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
@Day(9)
|
@Day(9)
|
||||||
class Day09(@Lines val input: Input<LongArray>) {
|
class Day09(@Lines val input: LongArray) {
|
||||||
|
|
||||||
private var part1Result = 0L
|
private var part1Result = 0L
|
||||||
|
|
||||||
fun part1(): Long? {
|
fun part1(): Long? {
|
||||||
val longs = input.value
|
for (windowStart in 0 until input.size - 26) {
|
||||||
|
val last = input[windowStart + 25]
|
||||||
for (windowStart in 0 until longs.size - 26) {
|
|
||||||
val last = longs[windowStart + 25]
|
|
||||||
if (!isValid(windowStart, last)) {
|
if (!isValid(windowStart, last)) {
|
||||||
part1Result = last
|
part1Result = last
|
||||||
return last
|
return last
|
||||||
@@ -27,8 +23,8 @@ class Day09(@Lines val input: Input<LongArray>) {
|
|||||||
private fun isValid(windowStart: Int, last: Long): Boolean {
|
private fun isValid(windowStart: Int, last: Long): Boolean {
|
||||||
for (i in windowStart until windowStart + 25) {
|
for (i in windowStart until windowStart + 25) {
|
||||||
for (j in windowStart + 1 until windowStart + 25) {
|
for (j in windowStart + 1 until windowStart + 25) {
|
||||||
val f = input.value[i]
|
val f = input[i]
|
||||||
val s = input.value[j]
|
val s = input[j]
|
||||||
if (f + s == last && f != s) return true
|
if (f + s == last && f != s) return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,10 +34,10 @@ class Day09(@Lines val input: Input<LongArray>) {
|
|||||||
fun part2(): Long {
|
fun part2(): Long {
|
||||||
var size = 2
|
var size = 2
|
||||||
while (true) {
|
while (true) {
|
||||||
for (startIndex in input.value.indices) {
|
for (startIndex in input.indices) {
|
||||||
val lastIndex = input.value.size - 1 - size
|
val lastIndex = input.size - 1 - size
|
||||||
if (startIndex + size > lastIndex) break
|
if (startIndex + size > lastIndex) break
|
||||||
val slice = input.value.sliceArray(startIndex..startIndex + size)
|
val slice = input.sliceArray(startIndex..startIndex + size)
|
||||||
if (slice.sum() == part1Result) return slice.minOrNull()!! + slice.maxOrNull()!!
|
if (slice.sum() == part1Result) return slice.minOrNull()!! + slice.maxOrNull()!!
|
||||||
}
|
}
|
||||||
size++
|
size++
|
||||||
@@ -49,8 +45,3 @@ class Day09(@Lines val input: Input<LongArray>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day09>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.api.list.primitive.MutableIntList
|
import org.eclipse.collections.api.list.primitive.MutableIntList
|
||||||
import org.eclipse.collections.impl.factory.primitive.IntLists
|
import org.eclipse.collections.impl.factory.primitive.IntLists
|
||||||
import org.eclipse.collections.impl.factory.primitive.IntLongMaps
|
import org.eclipse.collections.impl.factory.primitive.IntLongMaps
|
||||||
|
|
||||||
@Day(10)
|
@Day(10)
|
||||||
class Day10(@Lines val input: Input<IntArray>) {
|
class Day10(@Lines val input: IntArray) {
|
||||||
|
|
||||||
fun part1(): Int {
|
fun part1(): Int {
|
||||||
val sorted = IntLists.mutable.of(0, *input.value).apply {
|
val sorted = IntLists.mutable.of(0, *input).apply {
|
||||||
sortThis()
|
sortThis()
|
||||||
add(last + 3)
|
add(last + 3)
|
||||||
}.toArray().toList()
|
}.toArray().toList()
|
||||||
@@ -29,7 +27,7 @@ class Day10(@Lines val input: Input<IntArray>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun part2(): Long {
|
fun part2(): Long {
|
||||||
val sorted: MutableIntList = IntLists.mutable.of(*input.value).apply { sortThis() }
|
val sorted: MutableIntList = IntLists.mutable.of(*input).apply { sortThis() }
|
||||||
|
|
||||||
val map = IntLongMaps.mutable.empty().apply {
|
val map = IntLongMaps.mutable.empty().apply {
|
||||||
put(0, 1L)
|
put(0, 1L)
|
||||||
@@ -43,8 +41,3 @@ class Day10(@Lines val input: Input<IntArray>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day10>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,34 +1,32 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
typealias Seats = Array<CharArray>
|
private typealias Seats = Array<CharArray>
|
||||||
|
|
||||||
fun Seats.deepClone(): Seats = map { it.clone() }.toTypedArray()
|
private fun Seats.deepClone(): Seats = map { it.clone() }.toTypedArray()
|
||||||
|
|
||||||
operator fun Seats.get(x: Int, y: Int): Char = this[y][x]
|
private operator fun Seats.get(x: Int, y: Int): Char = this[y][x]
|
||||||
operator fun Seats.set(x: Int, y: Int, value: Char) {
|
private operator fun Seats.set(x: Int, y: Int, value: Char) {
|
||||||
this[y][x] = value
|
this[y][x] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun Seats.contains(xy: Pair<Int, Int>): Boolean {
|
private operator fun Seats.contains(xy: Pair<Int, Int>): Boolean {
|
||||||
val (x, y) = xy
|
val (x, y) = xy
|
||||||
return x in 0 until width && y in 0 until height
|
return x in 0 until width && y in 0 until height
|
||||||
}
|
}
|
||||||
|
|
||||||
val Seats.width get() = first().size
|
private val Seats.width get() = first().size
|
||||||
val Seats.height get() = size
|
private val Seats.height get() = size
|
||||||
|
|
||||||
fun Seats.asGridString() = joinToString("\n") { it.joinToString("") }
|
private fun Seats.asGridString() = joinToString("\n") { it.joinToString("") }
|
||||||
fun Seats.countOccupied() = sumBy { it.count { it == '#' } }
|
private fun Seats.countOccupied() = sumBy { it.count { it == '#' } }
|
||||||
|
|
||||||
@Day(11)
|
@Day(11)
|
||||||
class Day11(@Lines val input: Input<List<String>>) {
|
class Day11(@Lines val input: List<String>) {
|
||||||
|
|
||||||
private val seats: Seats = input.value.map { it.toCharArray() }.toTypedArray()
|
private val seats: Seats = input.map { it.toCharArray() }.toTypedArray()
|
||||||
|
|
||||||
private val directions = listOf(
|
private val directions = listOf(
|
||||||
-1 to -1,
|
-1 to -1,
|
||||||
@@ -116,8 +114,3 @@ class Day11(@Lines val input: Input<List<String>>) {
|
|||||||
fun part2() = findLastRepeating(seats, ::progress2).countOccupied()
|
fun part2() = findLastRepeating(seats, ::progress2).countOccupied()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day11>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
@Day(12)
|
@Day(12)
|
||||||
class Day12(@Lines val input: Input<List<String>>) {
|
class Day12(@Lines val input: List<String>) {
|
||||||
|
|
||||||
fun part1(): Int {
|
fun part1(): Int {
|
||||||
var x = 0
|
var x = 0
|
||||||
@@ -16,7 +14,7 @@ class Day12(@Lines val input: Input<List<String>>) {
|
|||||||
|
|
||||||
val dirs = listOf("N", "E", "S", "W")
|
val dirs = listOf("N", "E", "S", "W")
|
||||||
|
|
||||||
input.value.forEach {
|
input.forEach {
|
||||||
val dir = it.take(1)
|
val dir = it.take(1)
|
||||||
val steps = it.drop(1).toInt()
|
val steps = it.drop(1).toInt()
|
||||||
|
|
||||||
@@ -50,7 +48,7 @@ class Day12(@Lines val input: Input<List<String>>) {
|
|||||||
var waypointX = 10
|
var waypointX = 10
|
||||||
var waypointY = -1
|
var waypointY = -1
|
||||||
|
|
||||||
input.value.forEach {
|
input.forEach {
|
||||||
val dir = it.take(1)
|
val dir = it.take(1)
|
||||||
val steps = it.drop(1).toInt()
|
val steps = it.drop(1).toInt()
|
||||||
|
|
||||||
@@ -79,8 +77,3 @@ class Day12(@Lines val input: Input<List<String>>) {
|
|||||||
return abs(x) + abs(y)
|
return abs(x) + abs(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day12>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,18 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
data class Bus(val index: Int, val id: Long)
|
private data class Bus(val index: Int, val id: Long)
|
||||||
|
|
||||||
@Day(13)
|
@Day(13)
|
||||||
class Day13(@Lines val input: Input<List<String>>) {
|
class Day13(@Lines val input: List<String>) {
|
||||||
|
|
||||||
fun part1(): Int {
|
fun part1(): Int {
|
||||||
val id = input.value[0].toInt()
|
val id = input[0].toInt()
|
||||||
|
|
||||||
val (busId, min) = input.value[1]
|
val (busId, min) = input[1]
|
||||||
.splitToSequence(",")
|
.splitToSequence(",")
|
||||||
.filterNot { it == "x" }
|
.filterNot { it == "x" }
|
||||||
.map { it.toInt() }
|
.map { it.toInt() }
|
||||||
@@ -29,7 +27,7 @@ class Day13(@Lines val input: Input<List<String>>) {
|
|||||||
private fun lcm(a: Long, b: Long): Long = a / gcd(a, b) * b
|
private fun lcm(a: Long, b: Long): Long = a / gcd(a, b) * b
|
||||||
|
|
||||||
fun part2(): Long {
|
fun part2(): Long {
|
||||||
val buses = input.value[1]
|
val buses = input[1]
|
||||||
.splitToSequence(",")
|
.splitToSequence(",")
|
||||||
.mapIndexedNotNull { index, bus ->
|
.mapIndexedNotNull { index, bus ->
|
||||||
if (bus == "x") null
|
if (bus == "x") null
|
||||||
@@ -48,8 +46,3 @@ class Day13(@Lines val input: Input<List<String>>) {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day13>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
|
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
|
||||||
import org.eclipse.collections.impl.factory.primitive.LongIntMaps
|
import org.eclipse.collections.impl.factory.primitive.LongIntMaps
|
||||||
|
|
||||||
@Day(14)
|
@Day(14)
|
||||||
class Day14(@Lines val input: Input<List<String>>) {
|
class Day14(@Lines val input: List<String>) {
|
||||||
|
|
||||||
private val memRe = "mem\\[(\\d+)] = (.*)$".toRegex()
|
private val memRe = "mem\\[(\\d+)] = (.*)$".toRegex()
|
||||||
|
|
||||||
@@ -20,7 +18,7 @@ class Day14(@Lines val input: Input<List<String>>) {
|
|||||||
|
|
||||||
var currentMask: String = ""
|
var currentMask: String = ""
|
||||||
|
|
||||||
for (line in input.value) {
|
for (line in input) {
|
||||||
if (line.startsWith("mask")) {
|
if (line.startsWith("mask")) {
|
||||||
currentMask = line.removePrefix("mask = ")
|
currentMask = line.removePrefix("mask = ")
|
||||||
} else {
|
} else {
|
||||||
@@ -46,7 +44,7 @@ class Day14(@Lines val input: Input<List<String>>) {
|
|||||||
|
|
||||||
var currentMask = ""
|
var currentMask = ""
|
||||||
|
|
||||||
for (line in input.value) {
|
for (line in input) {
|
||||||
if (line[1] == 'a') {
|
if (line[1] == 'a') {
|
||||||
currentMask = line.substring(7)
|
currentMask = line.substring(7)
|
||||||
} else {
|
} else {
|
||||||
@@ -93,8 +91,3 @@ class Day14(@Lines val input: Input<List<String>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day14>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -2,16 +2,14 @@ package be.vandewalleh.aoc.days
|
|||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Csv
|
import be.vandewalleh.aoc.utils.input.Csv
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
|
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
|
||||||
|
|
||||||
@Day(15)
|
@Day(15)
|
||||||
class Day15(@Csv val input: Input<IntArray>) {
|
class Day15(@Csv val input: IntArray) {
|
||||||
|
|
||||||
private fun run(until: Int): Int {
|
private fun run(until: Int): Int {
|
||||||
val start = input.value
|
val start = input
|
||||||
|
|
||||||
val map = IntObjectMaps.mutable.empty<IntArray>()
|
val map = IntObjectMaps.mutable.empty<IntArray>()
|
||||||
|
|
||||||
@@ -43,11 +41,3 @@ class Day15(@Csv val input: Input<IntArray>) {
|
|||||||
|
|
||||||
fun part2() = run(until = 30000000)
|
fun part2() = run(until = 30000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
|
||||||
// val input = Input(intArrayOf(3, 1, 2))
|
|
||||||
with(createDay<Day15>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,8 +2,6 @@ package be.vandewalleh.aoc.days
|
|||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Groups
|
import be.vandewalleh.aoc.utils.input.Groups
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.api.multimap.list.ListMultimap
|
import org.eclipse.collections.api.multimap.list.ListMultimap
|
||||||
import org.eclipse.collections.api.multimap.list.MutableListMultimap
|
import org.eclipse.collections.api.multimap.list.MutableListMultimap
|
||||||
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
|
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
|
||||||
@@ -11,11 +9,11 @@ import org.eclipse.collections.impl.factory.Multimaps
|
|||||||
import org.eclipse.collections.impl.multimap.list.FastListMultimap
|
import org.eclipse.collections.impl.multimap.list.FastListMultimap
|
||||||
|
|
||||||
@Day(16)
|
@Day(16)
|
||||||
class Day16(@Groups val input: Input<List<List<String>>>) {
|
class Day16(@Groups val input: List<List<String>>) {
|
||||||
|
|
||||||
private val rangesGroup = input.value[0]
|
private val rangesGroup = input[0]
|
||||||
private val myTicket = input.value[1][1]
|
private val myTicket = input[1][1]
|
||||||
private val nearbyTicketsGroup = input.value[2].drop(1)
|
private val nearbyTicketsGroup = input[2].drop(1)
|
||||||
|
|
||||||
private val rangeRe = "(\\d+)-(\\d+)".toRegex()
|
private val rangeRe = "(\\d+)-(\\d+)".toRegex()
|
||||||
|
|
||||||
@@ -148,8 +146,3 @@ class Day16(@Groups val input: Input<List<List<String>>>) {
|
|||||||
return rangesByName
|
return rangesByName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day16>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
data class Point(val x: Int, val y: Int, val z: Int)
|
private data class Point(val x: Int, val y: Int, val z: Int)
|
||||||
data class Point4(val x: Int, val y: Int, val z: Int, val blah: Int)
|
private data class Point4(val x: Int, val y: Int, val z: Int, val blah: Int)
|
||||||
|
|
||||||
enum class State { Active, Inactive }
|
private enum class State { Active, Inactive }
|
||||||
|
|
||||||
@Day(17)
|
@Day(17)
|
||||||
class Day17(@Lines val input: Input<List<String>>) {
|
class Day17(@Lines val input: List<String>) {
|
||||||
|
|
||||||
fun part1(): Int {
|
fun part1(): Int {
|
||||||
val grid = parseGrid { x, y -> Point(x, y, 0) }
|
val grid = parseGrid { x, y -> Point(x, y, 0) }
|
||||||
@@ -27,7 +25,7 @@ class Day17(@Lines val input: Input<List<String>>) {
|
|||||||
|
|
||||||
private fun <T> parseGrid(pointFactory: (x: Int, y: Int) -> T): MutableMap<T, State> {
|
private fun <T> parseGrid(pointFactory: (x: Int, y: Int) -> T): MutableMap<T, State> {
|
||||||
val grid = mutableMapOf<T, State>()
|
val grid = mutableMapOf<T, State>()
|
||||||
input.value.forEachIndexed { index, row ->
|
input.forEachIndexed { index, row ->
|
||||||
row.forEachIndexed { col, char ->
|
row.forEachIndexed { col, char ->
|
||||||
val state = if (char == '#') State.Active else State.Inactive
|
val state = if (char == '#') State.Active else State.Inactive
|
||||||
grid[pointFactory(index, col)] = state
|
grid[pointFactory(index, col)] = state
|
||||||
@@ -87,8 +85,3 @@ class Day17(@Lines val input: Input<List<String>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day17>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
enum class Operator { Add, Multiply }
|
private enum class Operator { Add, Multiply }
|
||||||
|
|
||||||
operator fun Operator.invoke(a: Long, b: Long) = when (this) {
|
private operator fun Operator.invoke(a: Long, b: Long) = when (this) {
|
||||||
Operator.Add -> a + b
|
Operator.Add -> a + b
|
||||||
Operator.Multiply -> a * b
|
Operator.Multiply -> a * b
|
||||||
}
|
}
|
||||||
@@ -20,10 +18,10 @@ private inline fun Logger.debug(msg: () -> Any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Day(18)
|
@Day(18)
|
||||||
class Day18(@Lines val input: Input<List<String>>) {
|
class Day18(@Lines val input: List<String>) {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger("Day18")
|
private val logger = LoggerFactory.getLogger("Day18")
|
||||||
private val lines = input.value.map { it.replace(" ", "") }
|
private val lines = input.map { it.replace(" ", "") }
|
||||||
|
|
||||||
private fun parseGroups(line: String): Map<Int, List<IntRange>> {
|
private fun parseGroups(line: String): Map<Int, List<IntRange>> {
|
||||||
var depth = 0
|
var depth = 0
|
||||||
@@ -170,8 +168,3 @@ class Day18(@Lines val input: Input<List<String>>) {
|
|||||||
.reduce { t, u -> t + u }
|
.reduce { t, u -> t + u }
|
||||||
.get()
|
.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day18>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -2,15 +2,12 @@ package be.vandewalleh.aoc.days
|
|||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Groups
|
import be.vandewalleh.aoc.utils.input.Groups
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
@Day(19)
|
@Day(19)
|
||||||
class Day19(@Groups val input: Input<List<List<String>>>) {
|
class Day19(@Groups val input: List<List<String>>) {
|
||||||
private val rules = input.value[0]
|
private val rules = input[0]
|
||||||
private val messages = input.value[1]
|
private val messages = input[1]
|
||||||
|
|
||||||
sealed class Rule {
|
sealed class Rule {
|
||||||
data class CharRule(val value: Char) : Rule()
|
data class CharRule(val value: Char) : Rule()
|
||||||
@@ -56,8 +53,3 @@ class Day19(@Groups val input: Input<List<List<String>>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day19>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.days.geometry.Grid
|
||||||
|
import be.vandewalleh.aoc.days.geometry.gridOf
|
||||||
|
import be.vandewalleh.aoc.days.geometry.transformations
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
import be.vandewalleh.aoc.utils.input.Groups
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
private typealias Tile = Grid<Char>
|
||||||
|
|
||||||
|
@Day(20)
|
||||||
|
class Day20(@Groups val input: List<List<String>>) {
|
||||||
|
private val tiles: Map<Int, Tile> = input
|
||||||
|
.map { it[0].let { it.substring(5 until it.indexOf(':')).toInt() } to it.drop(1) }
|
||||||
|
.associate { (id, tile) -> id to gridOf(tile) }
|
||||||
|
|
||||||
|
private fun Tile.allEdges() = listOf(edges(), edges().map { it.reversed() }).flatten()
|
||||||
|
|
||||||
|
private fun edgesMatch(a: Tile, b: Tile): Boolean {
|
||||||
|
val edges = b.allEdges()
|
||||||
|
return a.allEdges().any { a -> edges.any { a == it } }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun combine(tiles: List<Tile>) = sequence {
|
||||||
|
for (i in 0 until tiles.lastIndex) {
|
||||||
|
val a = tiles[i]
|
||||||
|
for (j in i + 1 until tiles.size) {
|
||||||
|
val b = tiles[j]
|
||||||
|
yield(a to b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tilesByNeighbourCount(): MutableMap<Int, MutableList<Tile>> {
|
||||||
|
val neighbours = combine(tiles.values.toList())
|
||||||
|
.filter { (a, b) -> edgesMatch(a, b) }
|
||||||
|
.map { it.toList() }
|
||||||
|
.flatten()
|
||||||
|
.groupBy { it }
|
||||||
|
.values
|
||||||
|
|
||||||
|
val map = mutableMapOf<Int, MutableList<Tile>>()
|
||||||
|
for (neighbour in neighbours) {
|
||||||
|
map.computeIfAbsent(neighbour.size) { mutableListOf() }.add(neighbour.first())
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
fun part1() = tilesByNeighbourCount()[2]!!
|
||||||
|
.map { tile -> tiles.entries.find { it.value == tile }!!.key.toLong() }
|
||||||
|
.reduce { acc, id -> acc * id }
|
||||||
|
|
||||||
|
private fun neighboursCount(grid: Grid<*>, x: Int, y: Int): Int {
|
||||||
|
var neighboursCount = 2
|
||||||
|
if (x != 0 && x != grid.lastColumnIndex) neighboursCount++
|
||||||
|
if (y != 0 && y != grid.lastRowIndex) neighboursCount++
|
||||||
|
return neighboursCount
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isLeftOk(grid: Grid<Tile?>, x: Int, y: Int, candidate: Tile) = grid[x - 1, y]
|
||||||
|
?.let { left -> candidate.firstColumn() == left.lastColumn() }
|
||||||
|
?: true
|
||||||
|
|
||||||
|
private fun isTopOk(grid: Grid<Tile?>, x: Int, y: Int, candidate: Tile) = grid[x, y - 1]
|
||||||
|
?.let { top -> candidate.firstRow() == top.lastRow() }
|
||||||
|
?: true
|
||||||
|
|
||||||
|
private fun isBottomOk(grid: Grid<*>, x: Int, y: Int, candidate: Tile, neighbours: Map<Int, List<Tile>>) =
|
||||||
|
if (y == grid.lastRowIndex) true
|
||||||
|
else neighbours[neighboursCount(grid, x, y + 1)]!!
|
||||||
|
.filterNot { it == candidate }
|
||||||
|
.count { it.transformations().any { candidate.lastColumn() == it.firstColumn() } } == 1
|
||||||
|
|
||||||
|
private fun isRightOk(grid: Grid<*>, x: Int, y: Int, candidate: Tile, neighbours: Map<Int, List<Tile>>) =
|
||||||
|
if (x == grid.lastColumnIndex) true
|
||||||
|
else neighbours[neighboursCount(grid, x + 1, y)]!!
|
||||||
|
.filterNot { it == candidate }
|
||||||
|
.count { it.transformations().any { candidate.lastRow() == it.firstRow() } } == 1
|
||||||
|
|
||||||
|
private fun assembleGrid(): Grid<Tile?> {
|
||||||
|
val size = sqrt(tiles.size.toDouble()).toInt()
|
||||||
|
val grid: Grid<Tile?> = Grid(Array(size) { Array(size) { null } })
|
||||||
|
|
||||||
|
val neighbours: MutableMap<Int, MutableList<Tile>> = tilesByNeighbourCount()
|
||||||
|
|
||||||
|
for (y in 0 until grid.height) {
|
||||||
|
for (x in 0 until grid.width) {
|
||||||
|
val neighboursCount = neighboursCount(grid, x, y)
|
||||||
|
val candidates = neighbours[neighboursCount]!!
|
||||||
|
|
||||||
|
val conditions = mutableListOf<(Tile) -> Boolean>()
|
||||||
|
conditions += { isLeftOk(grid, x, y, it) }
|
||||||
|
conditions += { isTopOk(grid, x, y, it) }
|
||||||
|
|
||||||
|
// why is this condition needed ?
|
||||||
|
if (x == 0 && y == 0) {
|
||||||
|
conditions += { isBottomOk(grid, x, y, it, neighbours) }
|
||||||
|
conditions += { isRightOk(grid, x, y, it, neighbours) }
|
||||||
|
}
|
||||||
|
|
||||||
|
var found: Tile? = null
|
||||||
|
|
||||||
|
outer@ for (candidate in candidates) {
|
||||||
|
for (transform in candidate.transformations()) {
|
||||||
|
if (conditions.all { it(transform) }) {
|
||||||
|
found = transform
|
||||||
|
candidates.remove(candidate)
|
||||||
|
break@outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check(found != null)
|
||||||
|
grid[x, y] = found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeGaps(grid: Grid<Tile?>) {
|
||||||
|
for (y in 0 until grid.height) {
|
||||||
|
for (x in 0 until grid.width) {
|
||||||
|
grid[x, y] = removeGaps(grid[x, y]!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeGaps(tile: Tile): Tile {
|
||||||
|
val oldData: ArrayList<ArrayList<Char>> = tile.data
|
||||||
|
val newData = ArrayList<ArrayList<Char>>(oldData.size - 2)
|
||||||
|
oldData.subList(1, oldData.size - 1).forEach { d ->
|
||||||
|
val l = ArrayList<Char>().apply {
|
||||||
|
addAll(d.subList(1, d.size - 1))
|
||||||
|
}
|
||||||
|
newData.add(l)
|
||||||
|
}
|
||||||
|
return Tile(newData)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun gridToTile(grid: Grid<Tile?>): Tile {
|
||||||
|
val newData = ArrayList<ArrayList<Char>>()
|
||||||
|
for (y in 0 until grid.height) {
|
||||||
|
val row = grid.row(y)
|
||||||
|
for (yy in 0 until row[0]!!.height) {
|
||||||
|
val combinedRow = ArrayList<Char>().also { newData.add(it) }
|
||||||
|
row.forEach { combinedRow.addAll(it!!.row(yy)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Tile(newData)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Tile.subGridData(startX: Int, startY: Int, width: Int, height: Int): List<List<Char>> {
|
||||||
|
val newData = ArrayList<ArrayList<Char>>()
|
||||||
|
for (y in startY until startY + height) {
|
||||||
|
val row = ArrayList<Char>().also { newData.add(it) }
|
||||||
|
for (x in startX until startX + width) {
|
||||||
|
row.add(this[x, y]!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newData
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<List<Char>>.isMonster(monster: List<List<Char>>): Boolean {
|
||||||
|
val monsterRe = monster.joinToString("") { it.joinToString("") }.replace(" ", ".").toRegex()
|
||||||
|
val str = this.joinToString("") { it.joinToString("") }
|
||||||
|
return monsterRe.matches(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun part2(): Int {
|
||||||
|
val grid = assembleGrid()
|
||||||
|
removeGaps(grid)
|
||||||
|
val megaTile = gridToTile(grid)
|
||||||
|
|
||||||
|
val monster: List<List<Char>> = """
|
||||||
|
| # |
|
||||||
|
|# ## ## ###|
|
||||||
|
| # # # # # # |
|
||||||
|
""".trimMargin("|").lines().map { it.toCharArray().dropLast(1) }
|
||||||
|
|
||||||
|
val monsterWidth = monster[0].size
|
||||||
|
val monsterHeight = 3
|
||||||
|
val monsterSquares = monster.flatten().count { it == '#' }
|
||||||
|
val squares = megaTile.data.flatten().count { it == '#' }
|
||||||
|
|
||||||
|
for (g in megaTile.transformations()) {
|
||||||
|
var count = 0
|
||||||
|
for (y in 0 until g.lastRowIndex - monsterHeight) {
|
||||||
|
for (x in 0 until g.lastColumnIndex - monsterWidth) {
|
||||||
|
val subgrid = g.subGridData(x, y, monsterWidth, monsterHeight)
|
||||||
|
if (subgrid.isMonster(monster)) {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count != 0) return squares - (count * monsterSquares)
|
||||||
|
}
|
||||||
|
error("No monsters found")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.api.factory.Bags
|
import org.eclipse.collections.api.factory.Bags
|
||||||
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
|
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
|
||||||
import org.eclipse.collections.impl.factory.Multimaps
|
import org.eclipse.collections.impl.factory.Multimaps
|
||||||
|
|
||||||
@Day(21)
|
@Day(21)
|
||||||
class Day21(@Lines val input: Input<List<String>>) {
|
class Day21(@Lines val input: List<String>) {
|
||||||
private val foods = input.value.map { line ->
|
private val foods = input.map { line ->
|
||||||
val parOpen = line.indexOf('(')
|
val parOpen = line.indexOf('(')
|
||||||
val ingredients = line.substring(0 until parOpen - 1).split(" ")
|
val ingredients = line.substring(0 until parOpen - 1).split(" ")
|
||||||
val allergens = line.substring(parOpen + 1 until line.length - 1).removePrefix("contains ").split(", ")
|
val allergens = line.substring(parOpen + 1 until line.length - 1).removePrefix("contains ").split(", ")
|
||||||
@@ -57,8 +55,3 @@ class Day21(@Lines val input: Input<List<String>>) {
|
|||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day21>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -2,15 +2,13 @@ package be.vandewalleh.aoc.days
|
|||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Groups
|
import be.vandewalleh.aoc.utils.input.Groups
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
data class PlayedGame(val a: List<Int>, val b: List<Int>)
|
private data class PlayedGame(val a: List<Int>, val b: List<Int>)
|
||||||
|
|
||||||
@Day(22)
|
@Day(22)
|
||||||
class Day22(@Groups val input: Input<List<List<String>>>) {
|
class Day22(@Groups val input: List<List<String>>) {
|
||||||
private val one = input.value[0].drop(1).map { it.toInt() }
|
private val one = input[0].drop(1).map { it.toInt() }
|
||||||
private val two = input.value[1].drop(1).map { it.toInt() }
|
private val two = input[1].drop(1).map { it.toInt() }
|
||||||
|
|
||||||
fun part1(): Long {
|
fun part1(): Long {
|
||||||
val oneDeque = ArrayDeque(one)
|
val oneDeque = ArrayDeque(one)
|
||||||
@@ -76,9 +74,3 @@ class Day22(@Groups val input: Input<List<List<String>>>) {
|
|||||||
return if (one.isEmpty()) 2 else 1
|
return if (one.isEmpty()) 2 else 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day22>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Text
|
import be.vandewalleh.aoc.utils.input.Text
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
@Day(23)
|
@Day(23)
|
||||||
class Day23(@Text val input: Input<String>) {
|
class Day23(@Text val input: String) {
|
||||||
private val cups = input.value.toCharArray().map { it.toString().toInt() }
|
private val cups = input.toCharArray().map { it.toString().toInt() }
|
||||||
|
|
||||||
private fun <T> ringSequence(head: Ring.Node<T>) = generateSequence(head) { it.next }
|
private fun <T> ringSequence(head: Ring.Node<T>) = generateSequence(head) { it.next }
|
||||||
|
|
||||||
@@ -111,8 +109,3 @@ class Day23(@Text val input: Input<String>) {
|
|||||||
return current.next
|
return current.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day23>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Lines
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.eclipse.collections.api.bag.Bag
|
import org.eclipse.collections.api.bag.Bag
|
||||||
import org.eclipse.collections.api.bag.MutableBag
|
import org.eclipse.collections.api.bag.MutableBag
|
||||||
import org.eclipse.collections.api.factory.Bags
|
import org.eclipse.collections.api.factory.Bags
|
||||||
|
|
||||||
@Day(24)
|
@Day(24)
|
||||||
class Day24(@Lines val input: Input<List<String>>) {
|
class Day24(@Lines val input: List<String>) {
|
||||||
|
|
||||||
|
private data class HexPoint(val x: Int, val y: Int, val z: Int) {
|
||||||
|
fun translate(other: HexPoint) = HexPoint(this.x + other.x, this.y + other.y, this.z + other.z)
|
||||||
|
}
|
||||||
|
|
||||||
private enum class Direction(vararg coordinates: Int) {
|
private enum class Direction(vararg coordinates: Int) {
|
||||||
E(1, -1, 0),
|
E(1, -1, 0),
|
||||||
@@ -19,7 +21,7 @@ class Day24(@Lines val input: Input<List<String>>) {
|
|||||||
NW(0, 1, -1),
|
NW(0, 1, -1),
|
||||||
NE(1, 0, -1);
|
NE(1, 0, -1);
|
||||||
|
|
||||||
val coordinates = coordinates
|
val coordinates = HexPoint(coordinates[0], coordinates[1], coordinates[2])
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseTile(line: String) = "e|se|sw|w|nw|ne".toRegex()
|
private fun parseTile(line: String) = "e|se|sw|w|nw|ne".toRegex()
|
||||||
@@ -28,31 +30,19 @@ class Day24(@Lines val input: Input<List<String>>) {
|
|||||||
.map { Direction.valueOf(it.toUpperCase()) }
|
.map { Direction.valueOf(it.toUpperCase()) }
|
||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
private val tiles = input.value.map { parseTile(it) }.map {
|
private val tiles = input.map { parseTile(it) }.map {
|
||||||
it.map { it.coordinates }
|
it.map { it.coordinates }.reduce { acc, ints -> acc.translate(ints) }
|
||||||
.reduce { acc, ints -> intArrayOf(acc[0] + ints[0], acc[1] + ints[1], acc[2] + ints[2]) }
|
|
||||||
.toList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun part1() = Bags.immutable.ofAll(tiles).selectBlacks().size()
|
fun part1() = Bags.immutable.ofAll(tiles).selectBlacks().size()
|
||||||
|
|
||||||
private fun Bag<List<Int>>.selectBlacks() = selectByOccurrences { it % 2 == 1 }
|
private fun Bag<HexPoint>.selectBlacks() = selectByOccurrences { it % 2 == 1 }
|
||||||
|
|
||||||
private fun List<Int>.adjacents(): List<List<Int>> {
|
private fun HexPoint.adjacents() = Direction.values().map { this.translate(it.coordinates) }
|
||||||
val (x, y, z) = this
|
|
||||||
return listOf(
|
|
||||||
listOf(x + 1, y - 1, z),
|
|
||||||
listOf(x, y - 1, z + 1),
|
|
||||||
listOf(x - 1, y, z + 1),
|
|
||||||
listOf(x - 1, y + 1, z),
|
|
||||||
listOf(x, y + 1, z - 1),
|
|
||||||
listOf(x + 1, y, z - 1),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// black -> odd
|
// black -> odd
|
||||||
// white -> even || not in bag -> !in black
|
// white -> even || not in bag -> !in black
|
||||||
private fun day(bag: MutableBag<List<Int>>) {
|
private fun day(bag: MutableBag<HexPoint>) {
|
||||||
val blacks = bag.selectBlacks().toSet()
|
val blacks = bag.selectBlacks().toSet()
|
||||||
|
|
||||||
val all = (bag + bag.flatMap { it.adjacents() }).toSet()
|
val all = (bag + bag.flatMap { it.adjacents() }).toSet()
|
||||||
@@ -73,8 +63,3 @@ class Day24(@Lines val input: Input<List<String>>) {
|
|||||||
return bag.selectBlacks().size()
|
return bag.selectBlacks().size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() = with(createDay<Day24>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
import be.vandewalleh.aoc.utils.input.Lines
|
||||||
|
|
||||||
|
@Day(25)
|
||||||
|
class Day25(@Lines val input: IntArray) {
|
||||||
|
private val doorPublicKey = input[0]
|
||||||
|
private val cardPublicKey = input[1]
|
||||||
|
|
||||||
|
private fun encryptionKey(loopSize: Int, publicKey: Int) = transformSubjectNumber(loopSize, publicKey)
|
||||||
|
|
||||||
|
private fun transformSubjectNumber(loopSize: Int, subjectNumber: Int): Int {
|
||||||
|
var number = 1L
|
||||||
|
repeat(loopSize) {
|
||||||
|
number *= subjectNumber
|
||||||
|
number %= 20201227
|
||||||
|
}
|
||||||
|
return number.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformSubjectNumberStartingWith(currentNumber: Long, subjectNumber: Int): Long {
|
||||||
|
var number = currentNumber
|
||||||
|
number *= subjectNumber
|
||||||
|
number %= 20201227
|
||||||
|
return number
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findLoopSize(expectedPublicKey: Long): Int {
|
||||||
|
var computedPublicKey = 1L
|
||||||
|
var loopSize = 0
|
||||||
|
do {
|
||||||
|
computedPublicKey = transformSubjectNumberStartingWith(computedPublicKey, 7)
|
||||||
|
loopSize++
|
||||||
|
} while (computedPublicKey != expectedPublicKey)
|
||||||
|
return loopSize
|
||||||
|
}
|
||||||
|
|
||||||
|
fun part1(): Int {
|
||||||
|
val cardLoopSize = findLoopSize(cardPublicKey.toLong())
|
||||||
|
return encryptionKey(cardLoopSize, doorPublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
|
|
||||||
|
fun main() = with(createDay<Day15>()) {
|
||||||
|
println(part1())
|
||||||
|
}
|
||||||
@@ -44,13 +44,6 @@ class Grid<T> {
|
|||||||
|
|
||||||
fun edges() = listOf(row(0), column(0), row(lastRowIndex), column(lastColumnIndex))
|
fun edges() = listOf(row(0), column(0), row(lastRowIndex), column(lastColumnIndex))
|
||||||
|
|
||||||
fun neighbours(x: Int, y: Int) = listOf(
|
|
||||||
x to y - 1,
|
|
||||||
x + 1 to y,
|
|
||||||
x to y + 1,
|
|
||||||
x - 1 to y,
|
|
||||||
).mapNotNull { this[x, y] }
|
|
||||||
|
|
||||||
override fun toString() = buildString {
|
override fun toString() = buildString {
|
||||||
data.forEach { line ->
|
data.forEach { line ->
|
||||||
append(line.joinToString(""))
|
append(line.joinToString(""))
|
||||||
-2
@@ -1,7 +1,5 @@
|
|||||||
package be.vandewalleh.aoc.days.geometry
|
package be.vandewalleh.aoc.days.geometry
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
private fun <T> ArrayList<T>.reversed(): ArrayList<T> {
|
private fun <T> ArrayList<T>.reversed(): ArrayList<T> {
|
||||||
val out = ArrayList<T>(this.size)
|
val out = ArrayList<T>(this.size)
|
||||||
asReversed().forEach { out.add(it) }
|
asReversed().forEach { out.add(it) }
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
1327981
|
||||||
|
2822615
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
org.slf4j.simpleLogger.logFile=System.out
|
||||||
|
org.slf4j.simpleLogger.showDateTime=true
|
||||||
|
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
|
||||||
|
org.slf4j.simpleLogger.defaultLogLevel=info
|
||||||
|
org.slf4j.simpleLogger.log.io.micronaut=info
|
||||||
|
org.slf4j.simpleLogger.log.io.micronaut.context.lifecycle=info
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import io.micronaut.context.BeanContext
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
import io.micronaut.context.getBean
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
class Day01Test {
|
class Day01Test {
|
||||||
|
|
||||||
private val day = BeanContext.run().getBean<Day01>()
|
private val day = createDay<Day01>()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `part1 result`() {
|
fun `part1 result`() {
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ class Day03Test {
|
|||||||
"#.##...#...",
|
"#.##...#...",
|
||||||
"#...##....#",
|
"#...##....#",
|
||||||
".#..#...#.#",
|
".#..#...#.#",
|
||||||
).let { Input(it) }
|
)
|
||||||
|
|
||||||
private val day03 = Day03(example)
|
private val day03 = Day03(example)
|
||||||
|
|
||||||
@@ -43,11 +43,13 @@ class Day03Test {
|
|||||||
private val day03 = createDay<Day03>()
|
private val day03 = createDay<Day03>()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Disabled
|
||||||
fun `part1 result`() {
|
fun `part1 result`() {
|
||||||
assertThat(day03.part1()).isEqualTo(294)
|
assertThat(day03.part1()).isEqualTo(294)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Disabled
|
||||||
fun `part2 result`() {
|
fun `part2 result`() {
|
||||||
assertThat(day03.part2()).isEqualTo(5774564250)
|
assertThat(day03.part2()).isEqualTo(5774564250)
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
@@ -26,7 +25,6 @@ class Day04Test {
|
|||||||
hcl:#cfa07d eyr:2025 pid:166559648
|
hcl:#cfa07d eyr:2025 pid:166559648
|
||||||
iyr:2011 ecl:brn hgt:59in
|
iyr:2011 ecl:brn hgt:59in
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
.let { Input(it) }
|
|
||||||
|
|
||||||
private val day04 = Day04(example)
|
private val day04 = Day04(example)
|
||||||
|
|
||||||
@@ -63,7 +61,7 @@ class Day04Test {
|
|||||||
hgt:59cm ecl:zzz
|
hgt:59cm ecl:zzz
|
||||||
eyr:2038 hcl:74454a iyr:2023
|
eyr:2038 hcl:74454a iyr:2023
|
||||||
pid:3556412378 byr:2007
|
pid:3556412378 byr:2007
|
||||||
""".trimIndent().let { Input(it) }
|
""".trimIndent()
|
||||||
|
|
||||||
assertThat(Day04(input).part2()).isEqualTo(0)
|
assertThat(Day04(input).part2()).isEqualTo(0)
|
||||||
}
|
}
|
||||||
@@ -83,7 +81,7 @@ class Day04Test {
|
|||||||
eyr:2022
|
eyr:2022
|
||||||
|
|
||||||
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
|
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
|
||||||
""".trimIndent().let { Input(it) }
|
""".trimIndent()
|
||||||
|
|
||||||
assertThat(Day04(input).part2()).isEqualTo(4)
|
assertThat(Day04(input).part2()).isEqualTo(4)
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.params.ParameterizedTest
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
import org.junit.jupiter.params.provider.CsvSource
|
import org.junit.jupiter.params.provider.CsvSource
|
||||||
@@ -20,7 +19,7 @@ class Day13Test {
|
|||||||
)
|
)
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
fun examples(buses: String, answer: Long) {
|
fun examples(buses: String, answer: Long) {
|
||||||
val input = Input(listOf("", buses))
|
val input = listOf("", buses)
|
||||||
assertThat(Day13(input).part2()).isEqualTo(answer)
|
assertThat(Day13(input).part2()).isEqualTo(answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import org.openjdk.jmh.annotations.*
|
import org.openjdk.jmh.annotations.*
|
||||||
import org.openjdk.jmh.infra.Blackhole
|
import org.openjdk.jmh.infra.Blackhole
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
import be.vandewalleh.aoc.utils.factory.createDay
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import org.openjdk.jmh.annotations.*
|
import org.openjdk.jmh.annotations.*
|
||||||
import org.openjdk.jmh.infra.Blackhole
|
import org.openjdk.jmh.infra.Blackhole
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package be.vandewalleh.aoc.days
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.params.ParameterizedTest
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
import org.junit.jupiter.params.provider.CsvSource
|
import org.junit.jupiter.params.provider.CsvSource
|
||||||
@@ -17,7 +16,7 @@ class Day18Test {
|
|||||||
])
|
])
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
fun examplesPart2(input: String, output: Long) {
|
fun examplesPart2(input: String, output: Long) {
|
||||||
val day18 = Day18(Input(listOf(input)))
|
val day18 = Day18(listOf(input))
|
||||||
assertThat(day18.part2()).isEqualTo(output)
|
assertThat(day18.part2()).isEqualTo(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
plugins {
|
||||||
|
id("aoc")
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass.set("be.vandewalleh.aoc.days.MainKt")
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
target area: x=20..30, y=-10..-5
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
target area: x=139..187, y=-148..-89
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import nre, strutils
|
||||||
|
|
||||||
|
let
|
||||||
|
regex = re"x=(-?\d+)..(-?\d+), y=(-?\d+)..(-?\d+)"
|
||||||
|
data = readFile("input.txt")
|
||||||
|
captures = data.find(regex).get.captures
|
||||||
|
x1 = captures[0].parseInt()
|
||||||
|
x2 = captures[1].parseInt()
|
||||||
|
y1 = captures[2].parseInt()
|
||||||
|
y2 = captures[3].parseInt()
|
||||||
|
minX = min(x1, x2)
|
||||||
|
maxX = max(x1, x2)
|
||||||
|
minY = min(y1, y2)
|
||||||
|
maxY = max(y1, y2)
|
||||||
|
|
||||||
|
proc land(dx: int, dy: int): int =
|
||||||
|
var dx = dx
|
||||||
|
var dy = dy
|
||||||
|
var x = 0
|
||||||
|
var y = 0
|
||||||
|
var high = y
|
||||||
|
while x < maxX and y > minY:
|
||||||
|
x += dx
|
||||||
|
y += dy
|
||||||
|
if dx > 0: dx -= 1
|
||||||
|
elif dx < 0: dx += 1
|
||||||
|
dy -= 1
|
||||||
|
high = max(high, y)
|
||||||
|
if x in minX..maxX and y in minY..maxY:
|
||||||
|
return high
|
||||||
|
return -1
|
||||||
|
|
||||||
|
var high = 0
|
||||||
|
var match = 0
|
||||||
|
for x in -1000..1000:
|
||||||
|
for y in -1000..1000:
|
||||||
|
let res = land(x, y)
|
||||||
|
if res != -1: match += 1
|
||||||
|
high = max(res, high)
|
||||||
|
|
||||||
|
echo(high)
|
||||||
|
echo(match)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
class Counter<K> : Iterable<Map.Entry<K, Long>> {
|
||||||
|
private val map = HashMap<K, Long>()
|
||||||
|
operator fun get(key: K) = map[key] ?: 0L
|
||||||
|
|
||||||
|
operator fun set(key: K, count: Long) {
|
||||||
|
map[key] = count
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun set(key: K, count: Int) {
|
||||||
|
if (count == 0)
|
||||||
|
map.remove(key)
|
||||||
|
else
|
||||||
|
map[key] = count.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toMap() = map.toMap(HashMap())
|
||||||
|
override fun toString() = map.toString()
|
||||||
|
|
||||||
|
fun minValue() = map.minOf { it.value }
|
||||||
|
fun maxValue() = map.maxOf { it.value }
|
||||||
|
|
||||||
|
override fun iterator() = toMap().iterator()
|
||||||
|
|
||||||
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun <T> Counter.Companion.invoke(items: Iterable<T>) = Counter<T>().apply { items.forEach { this[it] += 1 } }
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day01 : BaseDay() {
|
||||||
|
private val items by lazy { input.lines.ints }
|
||||||
|
|
||||||
|
override fun part1(): Int {
|
||||||
|
var count = 0
|
||||||
|
for (i in 0 until items.size - 1) {
|
||||||
|
if (items[i] < items[i + 1]) count++
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Int {
|
||||||
|
var count = 0
|
||||||
|
for (i in 0 until items.size - 3) {
|
||||||
|
val a = items.drop(i).take(3).sum()
|
||||||
|
val b = items.drop(i + 1).take(3).sum()
|
||||||
|
if (b > a) count++
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day02 : BaseDay() {
|
||||||
|
private val lines by lazy { input.lines.value.map { it.split(' ').let { it[0] to it[1].toInt() } } }
|
||||||
|
|
||||||
|
override fun part1(): Int {
|
||||||
|
var horizontalPosition = 0
|
||||||
|
var depth = 0
|
||||||
|
lines.forEach { (direction, value) ->
|
||||||
|
when (direction) {
|
||||||
|
"forward" -> horizontalPosition += value
|
||||||
|
"down" -> depth += value
|
||||||
|
"up" -> depth -= value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return horizontalPosition * depth
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Any {
|
||||||
|
var horizontalPosition = 0
|
||||||
|
var depth = 0
|
||||||
|
var aim = 0
|
||||||
|
lines.forEach { (direction, value) ->
|
||||||
|
when (direction) {
|
||||||
|
"forward" -> {
|
||||||
|
horizontalPosition += value
|
||||||
|
depth += aim * value
|
||||||
|
}
|
||||||
|
"down" -> aim += value
|
||||||
|
"up" -> aim -= value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return horizontalPosition * depth
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day03 : BaseDay() {
|
||||||
|
override fun part1(): Int {
|
||||||
|
val moreOnes = input.lines.value[0].indices
|
||||||
|
.map { i -> input.lines.value.map { it[i] } }
|
||||||
|
.map { it.count { it == '1' } >= it.size / 2 }
|
||||||
|
|
||||||
|
val gamma = moreOnes.joinToString("") { if (it) "1" else "0" }.toInt(radix = 2)
|
||||||
|
val epsilon = moreOnes.joinToString("") { if (!it) "1" else "0" }.toInt(radix = 2)
|
||||||
|
return gamma * epsilon
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Any {
|
||||||
|
val o2 = findNumber(input.lines.value) { ones, zeros -> if (ones >= zeros) '1' else '0' }
|
||||||
|
val co2 = findNumber(input.lines.value) { ones, zeros -> if (zeros <= ones) '0' else '1' }
|
||||||
|
return o2 * co2
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findNumber(input: List<String>, keep: (Int, Int) -> Char): Int {
|
||||||
|
var numbers = input
|
||||||
|
for (i in this.input.lines.value[0].indices) {
|
||||||
|
if (numbers.size == 1) break
|
||||||
|
val eachCount = numbers.map { it[i] }.groupingBy { it }.eachCount()
|
||||||
|
val ones = eachCount['1'] ?: 0
|
||||||
|
val zeros = eachCount['0'] ?: 0
|
||||||
|
val maj = keep(ones, zeros)
|
||||||
|
numbers = numbers.filter { it[i] == maj }
|
||||||
|
}
|
||||||
|
return numbers[0].toInt(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day04 : BaseDay() {
|
||||||
|
private val numbers by lazy { input.lines.value[0].split(',').map { it.toInt() } }
|
||||||
|
private val boards by lazy {
|
||||||
|
input.text.split("\n\n")
|
||||||
|
.drop(1)
|
||||||
|
.map { it.lines().map { it.trim().split("\\s+".toRegex()).map { it.toInt() } } }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val results by lazy { boards.map { playBoard(it) } }
|
||||||
|
|
||||||
|
override fun part1() = results.minByOrNull { it.first }!!.second
|
||||||
|
override fun part2() = results.maxByOrNull { it.first }!!.second
|
||||||
|
|
||||||
|
private fun playBoard(board: List<List<Int>>): Pair<Int, Int> {
|
||||||
|
for (round in numbers.indices) {
|
||||||
|
val usedNumbers = numbers.take(round)
|
||||||
|
for (line in board + board[0].indices.map { col -> board.map { it[col] } }) {
|
||||||
|
if (usedNumbers.containsAll(line)) {
|
||||||
|
val unmarkedNumbers = board.flatten().toMutableSet().also { it.removeAll(usedNumbers) }
|
||||||
|
return round to unmarkedNumbers.sum() * usedNumbers.last()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error("No wins")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day05 : BaseDay() {
|
||||||
|
|
||||||
|
data class Point(val x: Int, val y: Int)
|
||||||
|
|
||||||
|
private val re = "(\\d+),(\\d+) -> (\\d+),(\\d+)".toRegex()
|
||||||
|
|
||||||
|
private fun path(start: Point, end: Point): Sequence<Point> {
|
||||||
|
val dx = end.x.compareTo(start.x)
|
||||||
|
val dy = end.y.compareTo(start.y)
|
||||||
|
return generateSequence(start) {
|
||||||
|
if (it == end) null
|
||||||
|
else Point(it.x + dx, it.y + dy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part1(): Int {
|
||||||
|
val visited = HashMap<Point, Int>()
|
||||||
|
input.lines.value
|
||||||
|
.map {
|
||||||
|
re.find(it)!!.destructured.let { (x1, y1, x2, y2) ->
|
||||||
|
Point(x1.toInt(), y1.toInt()) to Point(x2.toInt(), y2.toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.filter { (start, end) -> start.x == end.x || start.y == end.y }
|
||||||
|
.flatMap { (start, end) -> path(start, end) }
|
||||||
|
.forEach { visited.compute(it) { _, value -> (value ?: 0) + 1 } }
|
||||||
|
|
||||||
|
return visited.values.count { it >= 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Int {
|
||||||
|
val visited = HashMap<Point, Int>()
|
||||||
|
input.lines.value
|
||||||
|
.map {
|
||||||
|
re.find(it)!!.destructured.let { (x1, y1, x2, y2) ->
|
||||||
|
Point(x1.toInt(), y1.toInt()) to Point(x2.toInt(), y2.toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flatMap { (start, end) -> path(start, end) }
|
||||||
|
.forEach { visited.compute(it) { _, value -> (value ?: 0) + 1 } }
|
||||||
|
|
||||||
|
return visited.values.count { it >= 2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day06 : BaseDay() {
|
||||||
|
override fun part1() = run(80)
|
||||||
|
override fun part2() = run(256)
|
||||||
|
|
||||||
|
private fun run(days: Int): Long {
|
||||||
|
var fish = LongArray(9)
|
||||||
|
input.csv.ints.forEach { fish[it] = fish[it] + 1 }
|
||||||
|
|
||||||
|
var newFish: LongArray
|
||||||
|
for (day in 1..days) {
|
||||||
|
newFish = LongArray(9)
|
||||||
|
for (timer in 8 downTo 1) {
|
||||||
|
newFish[timer - 1] = fish[timer]
|
||||||
|
}
|
||||||
|
newFish[8] = fish[0]
|
||||||
|
newFish[6] = fish[0] + newFish[6]
|
||||||
|
fish = newFish
|
||||||
|
}
|
||||||
|
return fish.sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day07 : BaseDay() {
|
||||||
|
|
||||||
|
override fun part1(): Any {
|
||||||
|
val ints = input.csv.ints
|
||||||
|
return (ints.minOrNull()!!..ints.maxOrNull()!!).minOf { target -> ints.sumOf { abs(it - target) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calc(position: Int, target: Int): Int {
|
||||||
|
val diff = abs(position - target)
|
||||||
|
var sum = 0
|
||||||
|
for (i in 1..diff) {
|
||||||
|
sum += diff - i + 1
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Any {
|
||||||
|
val ints = input.csv.ints
|
||||||
|
return (ints.minOrNull()!!..ints.maxOrNull()!!).minOf { target -> ints.sumOf { calc(it, target) } }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day08 : BaseDay() {
|
||||||
|
|
||||||
|
override fun part1() = input.lines.value
|
||||||
|
.map { it.split(" | ")[1].split(" ") }
|
||||||
|
.sumOf { it.count { it.length in setOf(2, 3, 4, 7) } }
|
||||||
|
|
||||||
|
override fun part2() = input.lines.value
|
||||||
|
.map { it.split(" | ").map { it.split(" ") } }
|
||||||
|
.sumOf { (pattern, digits) ->
|
||||||
|
val patterns = decodePatterns(pattern)
|
||||||
|
digits.map { patterns[it.sortChars()] }.joinToString("").toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decodePatterns(patterns: List<String>): Map<String, Int> {
|
||||||
|
val result = Array(10) { "" }
|
||||||
|
|
||||||
|
result[1] = patterns.single { it.length == 2 }
|
||||||
|
result[7] = patterns.single { it.length == 3 }
|
||||||
|
result[4] = patterns.single { it.length == 4 }
|
||||||
|
result[8] = patterns.single { it.length == 7 }
|
||||||
|
|
||||||
|
val frequency = patterns.flatMap { it.toCharArray().toList() }.groupBy { it }.mapValues { it.value.size }
|
||||||
|
val a = (result.letters(7) - result.letters(1)).first()
|
||||||
|
val b = frequency.findKey { it.value == 6 }
|
||||||
|
val c = frequency.findKey { it.value == 8 && it.key != a }
|
||||||
|
val d = frequency.findKey { it.value == 7 && it.key in result.letters(4) }
|
||||||
|
val e = frequency.findKey { it.value == 4 }
|
||||||
|
val f = frequency.findKey { it.value == 9 }
|
||||||
|
|
||||||
|
result[0] = patterns.find { it.length == 6 && d !in it }!!
|
||||||
|
result[2] = patterns.find { it.length == 5 && b !in it && f !in it }!!
|
||||||
|
result[3] = patterns.find { it.length == 5 && b !in it && e !in it }!!
|
||||||
|
result[5] = patterns.find { it.length == 5 && c !in it && e !in it }!!
|
||||||
|
result[6] = patterns.find { it.length == 6 && c !in it }!!
|
||||||
|
result[9] = patterns.find { it.length == 6 && e !in it }!!
|
||||||
|
|
||||||
|
return result.mapIndexed { index, value -> value.sortChars() to index }.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Array<String>.letters(number: Int) = this[number].toCharArray().toSet()
|
||||||
|
private fun <K, V> Map<K, V>.findKey(predicate: (Map.Entry<K, V>) -> Boolean) = entries.find(predicate)!!.key
|
||||||
|
private fun String.sortChars() = toCharArray().sorted().joinToString("")
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
private data class Point(val x: Int, val y: Int)
|
||||||
|
private fun Point.adjacents() = listOf(copy(y = y - 1), copy(x = x + 1), copy(y = y + 1), copy(x = x - 1))
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day09 : BaseDay() {
|
||||||
|
|
||||||
|
private val map by lazy {
|
||||||
|
input.lines.value.flatMapIndexed { y, line ->
|
||||||
|
line.mapIndexed { x, value -> Point(x, y) to value.digitToInt() }
|
||||||
|
}.filterNot { it.second == 9 }.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val lows by lazy {
|
||||||
|
map.keys.filter { point -> point.adjacents().mapNotNull { map[it] }.all { it > map[point]!! } }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part1() = lows.sumOf { map[it]!! + 1 }
|
||||||
|
|
||||||
|
override fun part2() = lows.map { low ->
|
||||||
|
val visited = HashSet<Point>().apply { add(low) }
|
||||||
|
generateSequence(hashSetOf(low)) {
|
||||||
|
it.asSequence()
|
||||||
|
.flatMap { it.adjacents() }
|
||||||
|
.filter { it in map }
|
||||||
|
.filterNot { it in visited }
|
||||||
|
.toHashSet()
|
||||||
|
.also { visited.addAll(it) }
|
||||||
|
.ifEmpty { null }
|
||||||
|
}.flatten().count()
|
||||||
|
}.sorted().takeLast(3).fold(1) { a, b -> a * b }
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day10 : BaseDay() {
|
||||||
|
private val chunks = mapOf(
|
||||||
|
')' to '(',
|
||||||
|
']' to '[',
|
||||||
|
'>' to '<',
|
||||||
|
'}' to '{',
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun part1(): Any {
|
||||||
|
val points = mapOf(
|
||||||
|
')' to 3,
|
||||||
|
']' to 57,
|
||||||
|
'}' to 1197,
|
||||||
|
'>' to 25137,
|
||||||
|
)
|
||||||
|
return input.lines.value.sumOf { line ->
|
||||||
|
val stack = mutableListOf<Char>()
|
||||||
|
for (char in line) {
|
||||||
|
if (char in chunks) {
|
||||||
|
if (stack.last() == chunks[char]!!) stack.removeLast()
|
||||||
|
else return@sumOf points[char]!!
|
||||||
|
} else {
|
||||||
|
stack.add(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Any {
|
||||||
|
val points = mapOf(
|
||||||
|
'(' to 1,
|
||||||
|
'[' to 2,
|
||||||
|
'{' to 3,
|
||||||
|
'<' to 4,
|
||||||
|
)
|
||||||
|
return input.lines.value.mapNotNull { line ->
|
||||||
|
val stack = mutableListOf<Char>()
|
||||||
|
for (char in line) {
|
||||||
|
if (char in chunks) {
|
||||||
|
if (stack.last() == chunks[char]!!) stack.removeLast()
|
||||||
|
else return@mapNotNull null
|
||||||
|
} else {
|
||||||
|
stack.add(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack.foldRight(0L) { char, score -> score * 5 + points[char]!! }
|
||||||
|
}.sorted().let { it[it.size / 2] }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package be.vandewalleh.aoc.days
|
||||||
|
|
||||||
|
import be.vandewalleh.aoc.utils.BaseDay
|
||||||
|
import be.vandewalleh.aoc.utils.input.Day
|
||||||
|
|
||||||
|
@Day
|
||||||
|
class Day11 : BaseDay() {
|
||||||
|
|
||||||
|
private data class Point(val x: Int, val y: Int) {
|
||||||
|
fun adjacents() = listOf(
|
||||||
|
copy(y = y - 1),
|
||||||
|
copy(x = x + 1),
|
||||||
|
copy(y = y + 1),
|
||||||
|
copy(x = x - 1),
|
||||||
|
copy(y = y - 1, x = x - 1),
|
||||||
|
copy(x = x + 1, y = y + 1),
|
||||||
|
copy(y = y + 1, x = x - 1),
|
||||||
|
copy(x = x + 1, y = y - 1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val map by lazy {
|
||||||
|
input.lines.value.flatMapIndexed { y, line ->
|
||||||
|
line.mapIndexed { x, value -> Point(x, y) to value.digitToInt() }
|
||||||
|
}.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part1(): Int {
|
||||||
|
val map = map.toMap(HashMap())
|
||||||
|
var count = 0
|
||||||
|
repeat(100) { count += step(map) }
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun step(map: HashMap<Point, Int>): Int {
|
||||||
|
map.keys.forEach { map[it] = map[it]!! + 1 }
|
||||||
|
val flashed = hashSetOf<Point>()
|
||||||
|
while (true) {
|
||||||
|
val count = map.entries.asSequence()
|
||||||
|
.filter { it.value > 9 }
|
||||||
|
.filter { it.key !in flashed }
|
||||||
|
.onEach { flashed += it.key }
|
||||||
|
.flatMap { it.key.adjacents() }
|
||||||
|
.filter { it in map }
|
||||||
|
.onEach { map[it] = map[it]!! + 1 }
|
||||||
|
.count()
|
||||||
|
|
||||||
|
if (count == 0) break
|
||||||
|
}
|
||||||
|
|
||||||
|
map.entries.filter { it.value > 9 }
|
||||||
|
.map { it.key }
|
||||||
|
.forEach { map[it] = 0 }
|
||||||
|
|
||||||
|
return flashed.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun part2(): Int {
|
||||||
|
val map = map.toMap(HashMap())
|
||||||
|
repeat(10000) { if (step(map) == map.size) return it + 1 }
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user