diff --git a/.classpath b/.classpath
index 5e8a55fe..b51d40f7 100644
--- a/.classpath
+++ b/.classpath
@@ -8,13 +8,14 @@
+
-
-
+
+
@@ -23,5 +24,10 @@
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index 5f2dbe11..ab2cc913 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ buildNumber.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
+
+.classpath
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
index f9fe3459..839d647e 100644
--- a/.settings/org.eclipse.core.resources.prefs
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index db24ee78..60af120b 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,15 +1,16 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=13
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.compliance=13
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=enabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=13
diff --git a/README.md b/README.md
index e8336bc7..1b4cf67c 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,114 @@
# adventOfCode(2019)
-Let's do this! Code first, refactor later(tm).
+Let's do this!
+
+Days:
+- [Day 1](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day1.java)
+- [Day 2](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day2.java)
+- [Day 3](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day3.java)
+- [Day 4](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day4.java)
+- [Day 5](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day5.java)
+- [Day 6](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day6.java)
+- [Day 7](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day7.java)
+- [Day 8](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day8.java)
+- [Day 9](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day9.java)
+- [Day 10](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day10.java)
+- [Day 11](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day11.java)
+- [Day 12](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day12.java)
+- [Day 13](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day13.java)
+- [Day 14](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day14.java)
+- [Day 15](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day15.java)
+- [Day 16](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day16.java)
+- [Day 17](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day17.java)
+- [Day 18](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day18.java)
+- [Day 19](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/days/Day19.java)
+
+Output of running [Main.java](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/Main.java):
+```
+Day 1:
+Part 1: 3514064
+Part 2: 5268207
+
+Day 2:
+Part 1: 8017076
+Part 2: 3146
+
+Day 3:
+Part 1: 303
+Part 2: 11222
+
+Day 4:
+Part 1: 481
+Part 2: 299
+
+Day 5:
+Part 1: 11049715
+Part 2: 2140710
+
+Day 6:
+Part 1: 186597
+Part 2: 412
+
+Day 7:
+Part 1: 116680
+Part 2: 89603079
+
+Day 8:
+Part 1: 1360
+Part 2:
+████ ███ █ █ ██ ███
+█ █ █ █ █ █ █ █ █
+███ █ █ █ █ █ █ █ █
+█ ███ █ █ ████ ███
+█ █ █ █ █ █ █ █
+█ █ ██ █ █ █ █
+
+Day 9:
+Part 1: 2518058886
+Part 2: 44292
+
+Day 10:
+Part 1: 299
+Part 2: 1419
+
+Day 11:
+Part 1: 2172
+Part 2:
+ ██ ████ █ ████ ████ ██ █ █ ███
+ █ █ █ █ █ █ █ █ █ █ █
+ █ ███ █ ███ ███ █ ████ █ █
+ █ █ █ █ █ █ ██ █ █ ███
+█ █ █ █ █ █ █ █ █ █ █
+ ██ ████ ████ ████ █ ███ █ █ █
+
+Day 12:
+Part 1: 13399
+Part 2: 312992287193064
+
+Day 13:
+Part 1: 320
+Part 2: 15156
+
+Day 14:
+Part 1: 485720
+Part 2: 3848998
+
+Day 15:
+Part 1: 380
+Part 2: 410
+
+Day 16:
+Part 1: 12541048
+Part 2: 62858988
+
+Day 17:
+Part 1: 7404
+Part 2: 929045
+
+Day 18:
+Part 1: 5402
+Part 2: 2138
+
+Day 19:
+Part 1: 179
+Part 2: 9760485
+```
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 07702b4e..9f19708b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,25 +1,45 @@
-
- 4.0.0
+
+ 4.0.0
- com.sbaars
- adventofcode2019
- 0.0.1-SNAPSHOT
- jar
+ com.sbaars
+ adventofcode2019
+ 0.0.1-SNAPSHOT
+ jar
- adventofcode2019
- http://maven.apache.org
+ adventofcode2019
+ http://maven.apache.org
-
- UTF-8
-
+
+ UTF-8
+ 8
+ 13
+ 13
+
-
-
- junit
- junit
- 3.8.1
- test
-
-
+
+
+ junit
+ junit
+ 3.8.2
+ test
+
+
+ org.projectlombok
+ lombok
+ 1.18.8
+ compile
+
+
+
+
+
+ maven-compiler-plugin
+
+ 13
+
+
+
+
diff --git a/src/main/java/com/sbaars/adventofcode2019/Main.java b/src/main/java/com/sbaars/adventofcode2019/Main.java
new file mode 100644
index 00000000..745d7c0d
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/Main.java
@@ -0,0 +1,17 @@
+package com.sbaars.adventofcode2019;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Main {
+ public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException, InvocationTargetException, NoSuchMethodException {
+ for(int day = 1; day<=19; day++) {
+ System.out.println("Day "+day+":");
+ Day instance = (Day)Class.forName("com.sbaars.adventofcode2019.days.Day"+day).getDeclaredConstructor().newInstance();
+ instance.printParts();
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Day.java b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
index caf3ee9d..badd6819 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Day.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
@@ -2,12 +2,14 @@
import java.io.IOException;
-public interface Day {
- public int part1() throws IOException;
- public int part2() throws IOException;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public interface Day extends DoesFileOperations {
+ public Object part1() throws IOException;
+ public Object part2() throws IOException;
public default void printParts() throws IOException {
- System.out.println("Part 1 = "+part1());
- System.out.println("Part 2 = "+part2());
+ System.out.println("Part 1: "+part1());
+ System.out.println("Part 2: "+part2());
}
}
diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
new file mode 100644
index 00000000..fafe9ff1
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -0,0 +1,65 @@
+package com.sbaars.adventofcode2019.common;
+
+import java.awt.Point;
+import java.util.Arrays;
+
+public enum Direction {
+ NORTH(1, 'U'), EAST(4, 'R'), SOUTH(2, 'D'), WEST(3, 'L');
+
+ public final int num;
+ public final int code;
+
+ private Direction(int num, char code) {
+ this.num = num;
+ this.code = code;
+ }
+
+ public static Direction getByDirCode(char code) {
+ return Arrays.stream(values()).filter(e -> e.code == code).findAny().get();
+ }
+
+ public Direction turn(boolean right) {
+ int cur = ordinal() + (right ? 1 : -1);
+ if(cur == Direction.values().length) cur = 0;
+ else if(cur == -1) cur = 3;
+ return Direction.values()[cur];
+ }
+
+ public Point move(Point currentLocation, int amount) {
+ switch (this) {
+ case SOUTH: return new Point(currentLocation.x, currentLocation.y+amount);
+ case NORTH: return new Point(currentLocation.x, currentLocation.y-amount);
+ case EAST: return new Point(currentLocation.x+amount, currentLocation.y);
+ case WEST: return new Point(currentLocation.x-amount, currentLocation.y);
+ }
+ throw new IllegalStateException("Non-existent Direction: "+this);
+ }
+
+ public Point move(Point currentLocation) {
+ return move(currentLocation, 1);
+ }
+
+ public Direction opposite() {
+ switch (this) {
+ case NORTH: return SOUTH;
+ case SOUTH: return NORTH;
+ case EAST: return WEST;
+ case WEST: return EAST;
+ }
+ throw new IllegalStateException("Non-existent Direction: "+this);
+ }
+
+ public static Direction getByMove(Point from, Point to) {
+ if(to.x > from.x) return EAST;
+ else if(to.x < from.x) return WEST;
+ else if(to.y > from.y) return SOUTH;
+ else if(to.y < from.y) return NORTH;
+ throw new IllegalStateException("From and to location are the same: "+from+", "+to);
+ }
+
+ public boolean leftOf(Direction robotDir) {
+ int n = this.ordinal()-1;
+ if(n == -1) n = values().length-1;
+ return robotDir.ordinal() == n;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java b/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java
new file mode 100644
index 00000000..e4de03c2
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java
@@ -0,0 +1,10 @@
+package com.sbaars.adventofcode2019.common;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+public interface ProcessesImages {
+ public default String printAsciiArray(int[][] pixels) {
+ return System.lineSeparator()+Arrays.stream(pixels).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "█").collect(Collectors.joining())).collect(Collectors.joining(System.lineSeparator()));
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day1.java b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
new file mode 100644
index 00000000..2aede117
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
@@ -0,0 +1,38 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Day1 implements Day
+{
+ public static void main(String[] args) throws IOException
+ {
+ new Day1().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ return createNumberStream().map(this::getFuel).sum();
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return createNumberStream().map(this::getRequiredFuel).sum();
+ }
+
+ private IntStream createNumberStream() throws IOException {
+ return Arrays.stream(readDay(1).split(System.lineSeparator())).mapToInt(Integer::parseInt);
+ }
+
+ private int getRequiredFuel(int mass) {
+ int fuel = getFuel(mass);
+ return fuel>0 ? fuel+getRequiredFuel(fuel) : 0;
+ }
+
+ private int getFuel(int mass) {
+ return (mass/3)-2;
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
new file mode 100644
index 00000000..226b165c
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -0,0 +1,78 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.OptionalDouble;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+import lombok.EqualsAndHashCode;
+
+public class Day10 implements Day {
+
+ private final List asteroids;
+ private Point baseLocation;
+
+ public Day10() throws IOException {
+ String[] mapString = Arrays.stream(readDay(10).split(System.lineSeparator())).toArray(String[]::new);
+ this.asteroids = IntStream.range(0, mapString.length).boxed().flatMap(i -> IntStream.range(0, mapString[i].length()).mapToObj(j -> new Point(j, i))).filter(p -> mapString[p.y].charAt(p.x) == '#').collect(Collectors.toList());
+ }
+
+ public static void main(String[] args) throws IOException {
+ new Day10().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ long[] nVisible = new long[asteroids.size()];
+ for(int i = 0; i nVisible[i] > nVisible[j] ? i : j).getAsInt());
+ return Arrays.stream(nVisible).max().getAsLong();
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ List asteroidList = asteroids.stream().map(e -> new Asteroid(baseLocation, e)).collect(Collectors.toList());
+ Asteroid prevDestroyed = new Asteroid();
+ for(int destroyed = 1; destroyed<200; destroyed++) {
+ Asteroid prev = prevDestroyed;
+ OptionalDouble nextRot = asteroidList.stream().mapToDouble(e -> e.rotation).filter(e -> e > prev.rotation).min();
+ if(nextRot.isPresent()) {
+ double nextRotation = nextRot.getAsDouble();
+ prevDestroyed = asteroidList.stream().filter(e -> e.rotation == nextRotation).reduce((a1, a2) -> a1.distance < a2.distance ? a1 : a2).get();
+ asteroidList.remove(prevDestroyed);
+ }
+ }
+ return prevDestroyed.position.x*100+prevDestroyed.position.y;
+ }
+
+ private long countNVisible(Point asteroid) {
+ return asteroids.stream().map(e -> new Asteroid(asteroid, e)).mapToDouble(e -> e.rotation).distinct().count();
+ }
+
+ @EqualsAndHashCode class Asteroid {
+ @EqualsAndHashCode.Exclude double rotation;
+ @EqualsAndHashCode.Exclude double distance;
+ Point position;
+
+ public Asteroid(Point center, Point me) {
+ this.rotation = calcRotationAngleInDegrees(center, me);
+ this.distance = me.distance(center);
+ this.position = me;
+ }
+
+ public Asteroid() {
+ this.rotation = Double.MIN_VALUE;
+ }
+
+ private double calcRotationAngleInDegrees(Point centerPt, Point targetPt) {
+ double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x) + Math.PI/2.0;
+ double angle = Math.toDegrees(theta);
+ return angle < 0 ? angle + 360 : angle;
+ }
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
new file mode 100644
index 00000000..934b1201
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -0,0 +1,67 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.Direction;
+import com.sbaars.adventofcode2019.common.ProcessesImages;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day11 implements Day, ProcessesImages {
+
+ public static void main(String[] args) throws IOException {
+ new Day11().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ return robotWalk(false);
+ }
+
+ private Object robotWalk(boolean startWhite) throws IOException {
+ IntcodeComputer c = new IntcodeComputer(11);
+ Point currentLocation = new Point(0,0);
+ Direction dir = Direction.NORTH;
+ final Set paintedOnce = new HashSet<>();
+ final Set whitePlaces = new HashSet<>();
+ if(startWhite)
+ whitePlaces.add(currentLocation);
+ while(true) {
+ c.setInput(whitePlaces.contains(currentLocation) ? 1 : 0);
+ long paintColor = c.run();
+ if(paintColor == IntcodeComputer.STOP_CODE)
+ break;
+ long turn = c.run();
+ paintedOnce.add(currentLocation);
+ if(paintColor == 1L) {
+ whitePlaces.add(currentLocation);
+ } else if(paintColor == 0L) {
+ whitePlaces.remove(currentLocation);
+ }
+
+ dir = dir.turn(turn == 1L);
+ currentLocation = dir.move(currentLocation);
+ }
+ return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
+ }
+
+ private String constructImage(Set whitePlaces) {
+ int cornerX = whitePlaces.stream().mapToInt(e -> e.x).min().getAsInt();
+ int cornerY = whitePlaces.stream().mapToInt(e -> e.y).min().getAsInt();
+ whitePlaces.forEach(e -> e.move(e.x - cornerX, e.y - cornerY));
+ int sizex = whitePlaces.stream().mapToInt(e -> e.x).max().getAsInt()+1;
+ int sizey = whitePlaces.stream().mapToInt(e -> e.y).max().getAsInt()+1;
+ int[][] places = new int[sizey][sizex];
+ for(Point p : whitePlaces)
+ places[p.y][p.x] = 1;
+ return printAsciiArray(places);
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return robotWalk(true);
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
new file mode 100644
index 00000000..2d269051
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -0,0 +1,102 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Day12 implements Day {
+
+ int[][] moons = {{-5,6,-11},{-8,-4,-2},{1,16,4},{11,11,-4}};
+ int[][] velocity = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
+
+ public static void main(String[] args) throws IOException {
+ new Day12().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ for(int n = 0; n<1000; n++) {
+ determineVelocity();
+ moveMoonsUsingVelocity();
+ }
+ int[] res = new int[moons.length];
+ for(int i = 0; i());
+ long[] res = new long[sets.size()];
+ for(long n = 0; true; n++) {
+ determineVelocity();
+ moveMoonsUsingVelocity();
+
+ for(int i = 0; i x == 0)) {
+ return lcm(res);
+ }
+ }
+ }
+ }
+ }
+
+ private void moveMoonsUsingVelocity() {
+ for(int i = 0; i moon2) {
+ velocity[i][dim]--;
+ velocity[j][dim]++;
+ }
+ }
+ }
+ }
+ }
+
+ private static long gcd(long a, long b) {
+ while (b > 0) {
+ long temp = b;
+ b = a % b; // % is remainder
+ a = temp;
+ }
+ return a;
+ }
+
+ private static long lcm(long a, long b) {
+ return a * (b / gcd(a, b));
+ }
+
+ private static long lcm(long[] input) {
+ long result = input[0];
+ for(int i = 1; i < input.length; i++) result = lcm(result, input[i]);
+ return result;
+ }
+
+
+ short[][] copy(short[][] arr){
+ short [][] myInt = new short[arr.length][];
+ for(int i = 0; i < arr.length; i++)
+ myInt[i] = arr[i].clone();
+ return myInt;
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day13.java b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
new file mode 100644
index 00000000..dc288e2b
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
@@ -0,0 +1,70 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day13 implements Day {
+
+ public static void main(String[] args) throws IOException {
+ new Day13().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ IntcodeComputer cp = new IntcodeComputer(13);
+ Set n = new HashSet();
+ while(true) {
+ long x = cp.run();
+ if(x == IntcodeComputer.STOP_CODE) return n.size();
+ long y = cp.run();
+ long tile = cp.run();
+ if(tile == 2)
+ n.add(new Point(Math.toIntExact(x), Math.toIntExact(y)));
+ }
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ IntcodeComputer cp = new IntcodeComputer(13, 1);
+ cp.setElement(0, 2);
+ int[][] field = new int[21][38];
+ int score = 0;
+ AtomicInteger paddlePos = new AtomicInteger(), ballPos = new AtomicInteger();
+ while(true) {
+ long x = cp.run();
+ if(x == IntcodeComputer.STOP_CODE)
+ return score;
+ long y = cp.run();
+ long tile = cp.run();
+ score = simulateField(cp, field, score, paddlePos, ballPos, Math.toIntExact(x), Math.toIntExact(y), Math.toIntExact(tile));
+ }
+ }
+
+ private int simulateField(IntcodeComputer cp, int[][] field, int score, AtomicInteger paddlePos, AtomicInteger ballPos, int x, int y, int tile) {
+ if(x == -1)
+ return tile;
+ else {
+ field[y][x] = tile;
+ if (tile == 3) {
+ paddlePos.set(x);
+ } else if (tile == 4) {
+ ballPos.set(x);
+ cp.setInput(provideInput(paddlePos, ballPos));
+ }
+ }
+ return score;
+ }
+
+ private int provideInput(AtomicInteger paddlePos, AtomicInteger ballPos) {
+ int ball = ballPos.get(), paddle = paddlePos.get();
+ if(ball>paddle) return 1;
+ else if(ball());
+ }
+
+ private Trade getTrade(String key) {
+ return Arrays.stream(trades).filter(e -> e.output.item.equals(key)).findAny().get();
+ }
+
+ private long findCost(Item buyingItem, LongCountMap leftOver) {
+ if(buyingItem.item.equals("ORE"))
+ return buyingItem.amount;
+ else if(buyingItem.amount <= leftOver.get(buyingItem.item)) {
+ leftOver.increment(buyingItem.item, -buyingItem.amount);
+ return 0;
+ }
+ buyingItem.amount-=leftOver.get(buyingItem.item);
+ leftOver.put(buyingItem.item, 0L);
+
+ return performTrade(buyingItem, leftOver);
+ }
+
+ private long performTrade(Item buyingItem, LongCountMap leftOver) {
+ Trade fuelTrade = getTrade(buyingItem.item);
+ long timesApplied = (long)Math.ceil((double)buyingItem.amount/(double)fuelTrade.output.amount);
+ long totalCost = 0;
+ for(Item cost : fuelTrade.input)
+ totalCost+=findCost(new Item(cost.amount*timesApplied, cost.item), leftOver);
+ leftOver.increment(buyingItem.item, fuelTrade.output.amount * timesApplied - buyingItem.amount);
+ return totalCost;
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ long oreLeft = 1000000000000L;
+ long fuel = 1;
+ while(true) {
+ long cost = findCost(new Item(fuel + 1, "FUEL"), new LongCountMap<>());
+ if (cost > oreLeft) {
+ return fuel;
+ } else {
+ fuel = Math.max(fuel + 1, (fuel + 1) * oreLeft / cost);
+ }
+ }
+ }
+
+ class Trade {
+ private final Item[] input;
+ private final Item output;
+
+ public Trade(String trade) {
+ String[] inputOutput = trade.split(" => ");
+ input = Arrays.stream(inputOutput[0].split(", ")).map(Item::new).toArray(Item[]::new);
+ output = new Item(inputOutput[1]);
+ }
+ }
+
+ class Item {
+ private long amount;
+ private final String item;
+
+ public Item(String item) {
+ String[] i = item.split(" ");
+ amount = Integer.parseInt(i[0]);
+ this.item = i[1];
+ }
+
+ public Item(long i, String string) {
+ amount = i;
+ item = string;
+ }
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
new file mode 100644
index 00000000..4e3c10ed
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -0,0 +1,99 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.Direction;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+import com.sbaars.adventofcode2019.pathfinding.Grid2d;
+
+public class Day15 implements Day {
+
+ public static final int UNEXPLORED = 3;
+ public static final int WALL = 0;
+ private static final int PATH = 1;
+ private static final int FINISH = 2;
+ private static final int BOARD_SIZE = 41;
+ private static final Point START_POINT = new Point(BOARD_SIZE/2+1,BOARD_SIZE/2+1);
+ int[][] grid = new int[BOARD_SIZE][BOARD_SIZE];
+
+ public static void main(String[] args) throws IOException {
+ new Day15().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ IntcodeComputer ic = new IntcodeComputer(15);
+ Point pos = START_POINT;
+ for(int[] row : grid) Arrays.fill(row, UNEXPLORED);
+ grid[pos.y][pos.x] = 1;
+ while(true) {
+ explore(pos, ic);
+ pos = moveToUnexploredPlace(pos, ic);
+ if(pos == null) {
+ Grid2d map2d = new Grid2d(grid, false);
+ return map2d.findPath(START_POINT, findPos(FINISH).get(0)).size()-1;
+ }
+ }
+ }
+
+ private Point moveToUnexploredPlace(Point pos, IntcodeComputer ic) {
+ List corridorSpaces = findPos(PATH);
+ for(Point p : corridorSpaces) {
+ if(hasAdjecent(p, UNEXPLORED)) {
+ Grid2d map2d = new Grid2d(grid, false);
+ List route = map2d.findPath(pos, p);
+ traverseRoute(ic, pos, route.subList(1, route.size()));
+ return p;
+ }
+ }
+ return null;
+ }
+
+ private void traverseRoute(IntcodeComputer ic, Point pos, List route) {
+ for(Point p : route) {
+ if(ic.run(Direction.getByMove(pos, p).num)!=1L)
+ throw new IllegalStateException("Illegal state at "+pos+" execute to "+p);
+ pos = p;
+ }
+ }
+
+ private boolean hasAdjecent(Point pos, int tile) {
+ return grid[pos.y+1][pos.x] == tile || grid[pos.y][pos.x+1] == tile || grid[pos.y-1][pos.x] == tile || grid[pos.y][pos.x-1] == tile;
+ }
+
+ private List findPos(int tile) {
+ List positions = new ArrayList<>();
+ for(int y = 0; y new Grid2d(grid, false).findPath(oxygenLeak, e).size()-1).max().getAsInt();
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day16.java b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
new file mode 100644
index 00000000..f2023f91
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
@@ -0,0 +1,68 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Day16 implements Day {
+
+ private static final int TARGET_POS = 5977341;
+ private final int[] input;
+
+ public Day16() throws IOException {
+ input = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
+ }
+
+ public static void main(String[] args) throws IOException {
+ new Day16().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ return calcRes(Arrays.copyOf(input, input.length), 0);
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return calcRes(repeat(input, 10000), TARGET_POS);
+ }
+
+ private Object calcRes(int[] nums, final int offset) {
+ int[] pattern = {0, 1, 0, -1};
+
+ int[] res = new int[nums.length];
+ for(int phase = 0; phase<100; phase++) {
+ int[] newNums = new int[nums.length+1];
+ for(int i=0;i= res.length) break;
+ loc=k;
+ }
+ res[i]=Math.abs(sum)%10;
+ }
+
+ System.arraycopy(res, 0, nums, 0, res.length);
+ }
+ return IntStream.range(offset, offset+8).map(i -> res[i]).mapToObj(Integer::toString).collect(Collectors.joining());
+ }
+
+ public static int[] repeat(int[] arr, int newLength) {
+ newLength = newLength * arr.length;
+ int[] dup = Arrays.copyOf(arr, newLength);
+ for (int last = arr.length; last != 0 && last < newLength; last <<= 1) {
+ System.arraycopy(dup, 0, dup, last, Math.min(last << 1, newLength) - last);
+ }
+ return dup;
+ }
+
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
new file mode 100644
index 00000000..9b180a8b
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -0,0 +1,161 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.Direction;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+import lombok.EqualsAndHashCode;
+
+public class Day17 implements Day {
+
+ char[][] grid = new char[48][48];
+
+ public Day17() throws IOException {
+ IntcodeComputer ic = new IntcodeComputer(17, 1);
+ long res;
+ int x = 0, y =0;
+ while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
+ if(res == 10) {
+ y++;
+ x= 0;
+ } else {
+ grid[y][x] = (char)res;
+ x++;
+ }
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ new Day17().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ int result = 0;
+ for(int y = 1; y instructions = new ArrayList<>();
+ List traversed = new ArrayList<>();
+ Direction dir;
+ Direction robotDir = Direction.NORTH;
+ while((dir = directionContainsSomethingAndUntraversed(grid, pos, traversed)) != null) {
+ int n;
+ for(n = 1; getGrid(grid, dir.move(pos, n)) == '#'; n++) traversed.add(dir.move(pos, n));
+ pos = dir.move(pos, n-1);
+ instructions.add(new Instruction(n-1, dir.leftOf(robotDir) ? Dir.R : Dir.L));
+ robotDir = dir;
+ }
+ String patterns = findPatterns(instructions) + "\nn\n";
+ long[] asciis = patterns.chars().mapToLong(e -> e).toArray();
+ IntcodeComputer ic = new IntcodeComputer(17, 2);
+ ic.setInput(asciis);
+ while(true) {
+ long res = ic.run();
+ if(res>255L)
+ return res;
+ }
+ }
+
+ private String findPatterns(List instructions) {
+ List> patterns = new ArrayList<>();
+ String patternString = "";
+ int start = 0;
+ for(int i = 0; i pattern = existing(instructions, patterns, i);
+ if(pattern!=null && start == i) {
+ start += pattern.size();
+ i+=pattern.size()-1;
+ patternString += ","+patterns.indexOf(pattern);
+ continue;
+ } else if(start!=i && (pattern != null || occurrences(instructions, instructions.subList(start, i+1))<3)) {
+ patternString += ","+patterns.size();
+ patterns.add(instructions.subList(start, i));
+ start = i;
+ i--;
+ }
+ }
+ return patternString.substring(1).replace("0", "A").replace("1", "B").replace("2", "C")+"\n"+patterns.stream().map(this::toString).collect(Collectors.joining("\n"));
+ }
+
+ private List existing(List instructions, List> patterns, int i){
+ for(List pattern : patterns)
+ if(i+pattern.size() <= instructions.size() && instructions.subList(i, i+pattern.size()).equals(pattern))
+ return pattern;
+ return null;
+ }
+
+ private int occurrences(List instructions, List subList) {
+ return Math.toIntExact(IntStream.range(0, instructions.size()-subList.size()).filter(i -> toString(instructions.subList(i, i+subList.size())).equals(toString(subList))).count());
+ }
+
+ public String toString(List i) {
+ return i.stream().map(Instruction::toString).collect(Collectors.joining(","));
+ }
+
+ private char getGrid(char[][] grid, Point p) {
+ if(p.x < 0 || p.y < 0 || p.x>=grid[0].length || p.y>=grid.length) return '.';
+ return grid[p.y][p.x];
+ }
+
+ private Direction directionContainsSomethingAndUntraversed(char[][] grid, Point pos, List traversed) {
+ Direction dir = Direction.NORTH;
+ for(int i = 0; i<4; i++) {
+ Point p = dir.move(pos);
+ if(getGrid(grid, p) == '#' && !traversed.contains(p)) {
+ return dir;
+ }
+ dir = dir.turn(true);
+ }
+ return null;
+ }
+
+ private List findPos(char[][] grid, char tile) {
+ List positions = new ArrayList<>();
+ for(int y = 0; y cachedResult = new HashMap<>();
+ private static final char[][] CHANGE_GRID = {
+ {'@', '#', '@'},
+ {'#', '#', '#'},
+ {'@', '#', '@'}
+ };
+ private final Point middle;
+
+ public Day18() throws IOException {
+ grid = Arrays.stream(readDay(18).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
+ charGrid = new CharGrid2d(grid, false);
+ middle = findPos('@').get(0);
+ }
+
+ public static void main(String[] args) throws IOException {
+ new Day18().printParts();
+ }
+
+ @Data @AllArgsConstructor class Route {
+ Point start;
+ Point end;
+ }
+
+ @Data @AllArgsConstructor class State{
+ List me;
+ TreeSet keys;
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ List me = new ArrayList<>();
+ me.add(middle);
+ return findRoutes(me);
+ }
+
+ private Object findRoutes(List me) {
+ List keys = findPos('a', 'z');
+ Map> routes = new HashMap<>();
+ List requiredRoutes = new ArrayList<>(keys);
+ requiredRoutes.addAll(me);
+ for(int i = 0; i r = charGrid.findPath(requiredRoutes.get(i), requiredRoutes.get(j));
+ if(!r.isEmpty())
+ routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
+ }
+ }
+ return findSteps(me, new TreeSet<>(), keys, routes);
+ }
+
+ public List getRoute(Map> routes, Point p1, Point p2){
+ List p = routes.get(new Route(p1, p2));
+ if(p != null)
+ return p;
+ else return routes.get(new Route(p2, p1));
+ }
+
+ public boolean canTakeRoute(List route, TreeSet keys) {
+ for(Point p : route) {
+ if(grid[p.y][p.x]>='A' && grid[p.y][p.x]<='Z' && !keys.contains(grid[p.y][p.x])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public int findSteps(List me, TreeSet collectedKeys, List keys, Map> routes) {
+ Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
+ if(cachedRes!=null) return cachedRes;
+ val possibleMoves = me.stream().flatMap(m -> keys.stream().map(p -> getRoute(routes, m, p))).filter(Objects::nonNull).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
+ List nSteps = new ArrayList<>();
+ for(List takenMove : possibleMoves) {
+ val myKeys = new TreeSet<>(collectedKeys);
+ val keyLocs = new ArrayList<>(keys);
+ Point newLoc = me.contains(takenMove.get(0)) ? takenMove.get(takenMove.size()-1) : takenMove.get(0);
+ Point oldLoc = me.contains(takenMove.get(0)) ? takenMove.get(0) : takenMove.get(takenMove.size()-1);
+ char collected = grid[newLoc.y][newLoc.x];
+ myKeys.add(Character.toUpperCase(collected));
+ keyLocs.remove(newLoc);
+ val me2 = new ArrayList<>(me);
+ me2.set(me.indexOf(oldLoc), newLoc);
+ nSteps.add(findSteps(me2, myKeys, keyLocs, routes) + takenMove.size()-1);
+ }
+ int res = nSteps.stream().mapToInt(e -> e).min().orElse(0);
+ cachedResult.put(new State(me, collectedKeys), res);
+ return res;
+ }
+
+ private List findPos(char tile) {
+ List positions = new ArrayList<>();
+ for(int y = 0; y findPos(char tile, char tile2) {
+ List positions = new ArrayList<>();
+ for(int y = 0; y= tile && grid[y][x] <= tile2)
+ positions.add(new Point(x, y));
+ }
+ }
+ return positions;
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ for(int y = 0; y portals = new HashMap<>();
+ private final Map portalLabel = new HashMap<>();
+ private final ListMap routes = new ListMap<>();
+ private final List portalsToTake = new ArrayList<>();
+ private Portal entry;
+ private Portal exit;
+
+ @Data @AllArgsConstructor class Portal {
+ Point pos;
+ boolean isOuter;
+ }
+
+ @Data @AllArgsConstructor class Route {
+ Portal goal;
+ int distance;
+ }
+
+ @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @AllArgsConstructor class State extends Visited {
+ int totalSteps;
+ String debug = "";
+
+ public State(String debug, int totalSteps, Visited vis) {
+ super(vis.pos, vis.level);
+ this.totalSteps = totalSteps;
+ this.debug = debug;
+ }
+ }
+
+ @Data @AllArgsConstructor @NoArgsConstructor class Visited {
+ Portal pos;
+ int level;
+ }
+
+ public Day20() throws IOException {
+ grid = Arrays.stream(readDay(20).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
+ charGrid = new CharGrid2d(grid, false);
+
+ int[] rows = {2, 26, 80, 104};
+ for(int row : rows) {
+ boolean addPortal = row == rows[0] || row == rows[rows.length-1];
+ for(int i = 2; i queue = new ArrayDeque<>();
+ final Set visited = new HashSet<>();
+ queue.add(new State("", 0, new Visited(entry, 0)));
+ while(true) {
+ State s = queue.poll();
+ if(s.level == 0 && s.pos.equals(exit)) {
+ System.out.println(s.debug);
+ return s.totalSteps-1;
+ }
+ else if(s.level < 0) continue;
+ if(!routes.containsKey(s.pos)) determineRoutes(s.pos);
+ for(Route route : routes.get(s.pos)) {
+ int level = s.level;
+ if(b) level+=route.goal.isOuter ? -1 : 1;
+ Visited vis = new Visited(route.goal, level);
+ if(!visited.contains(vis)) {
+ visited.add(vis);
+ queue.add(new State(s.debug+" "+(route.goal.isOuter ? '-' : '+')+portalLabel.get(route.goal)+":"+(s.totalSteps + route.distance), s.totalSteps + route.distance, vis));
+ }
+ }
+ }
+ }
+
+ private void determineRoutes(Portal p) {
+ for(Portal portal : portalsToTake) {
+ if(!portal.pos.equals(p.pos)) {
+ List route = charGrid.findPath(p.pos, portal.pos);
+ if(!route.isEmpty()) routes.addTo(p, new Route(teleport(portal), route.size()));
+ }
+ }
+ }
+
+ private Portal teleport(Portal portal) {
+ Portal[] thisPortal = portals.get(portalLabel.get(portal));
+ if(portal.equals(exit)) return exit;
+ if(portal.equals(thisPortal[0])) return thisPortal[1];
+ return thisPortal[0];
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return findRoutes(true);
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
new file mode 100644
index 00000000..27b93927
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -0,0 +1,106 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.Direction;
+
+import lombok.EqualsAndHashCode;
+
+public class Day3 implements Day
+{
+ private Set intersect;
+
+ public Day3() throws IOException {
+ String[] strings = Arrays.stream(readDay(3).split(System.lineSeparator())).toArray(String[]::new);
+ Walk[] walks1 = mapToWalks(strings[0]), walks2 = mapToWalks(strings[1]);
+ Set walkedLocations = new HashSet<>();
+ calculateDistance(walks1, walkedLocations, false);
+ this.intersect = calculateDistance(walks2, walkedLocations, true);
+ }
+
+ public static void main(String[] args) throws IOException {
+ new Day3().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ return intersect.stream().mapToInt(e -> distance(e.point)).min().orElse(Integer.MAX_VALUE);
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return intersect.stream().mapToInt(e -> e.steps).min().orElse(Integer.MAX_VALUE);
+ }
+
+ private Set calculateDistance(Walk[] walks1, Set walkedLocations, boolean collect) {
+ Set intersectingLocations = new HashSet<>();
+ int x = 0, y = 0, steps = 0;
+ for(Walk walk : walks1) {
+ for(;walk.distance>0;walk.distance--) {
+ switch(walk.dir) {
+ case NORTH: y++; break;
+ case SOUTH: y--; break;
+ case WEST: x--; break;
+ case EAST: x++; break;
+ }
+ performStep(walkedLocations, collect, intersectingLocations, x, y, steps);
+ steps++;
+ }
+ }
+ return intersectingLocations;
+ }
+
+ private void performStep(Set walkedLocations, boolean collect, Set intersectingLocations, int x, int y, int steps) {
+ Step currentStep = new Step(new Point(x,y), steps);
+ if(collect) {
+ if(walkedLocations.contains(currentStep) && !intersectingLocations.contains(currentStep)) {
+ Step step = walkedLocations.stream().filter(e -> e.equals(currentStep)).findAny().get();
+ intersectingLocations.add(step);
+ step.combine(currentStep);
+ }
+ } else {
+ walkedLocations.add(currentStep);
+ }
+ }
+
+ public int distance(Point p) {
+ return Math.abs(p.x) + Math.abs(p.y);
+ }
+
+ private Walk[] mapToWalks(String string) {
+ return Arrays.stream(string.split(",")).map(Walk::new).toArray(Walk[]::new);
+ }
+
+ class Walk {
+ private final Direction dir;
+ private int distance;
+
+ public Walk(String code) {
+ this.dir = Direction.getByDirCode(code.charAt(0));
+ this.distance = Integer.parseInt(code.substring(1));
+ }
+ }
+
+ @EqualsAndHashCode class Step {
+ private final Point point;
+ @EqualsAndHashCode.Exclude private int steps;
+ @EqualsAndHashCode.Exclude private boolean isCombined = false;
+
+ public Step(Point point, int steps) {
+ this.point = point;
+ this.steps = steps + 1;
+ }
+
+ public void combine(Step step) {
+ if(!isCombined) {
+ steps+=step.steps;
+ isCombined = true;
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day4.java b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
new file mode 100644
index 00000000..5031388b
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
@@ -0,0 +1,57 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Day4 implements Day {
+
+ public Day4() {}
+
+ public static void main(String[] args) throws IOException {
+ new Day4().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ return checkPasswords(false);
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return checkPasswords(true);
+ }
+
+ public long meetsCriteria(int lowerBound, int higherBound, boolean checkGroup) {
+ return IntStream.range(lowerBound, higherBound+1).filter(e -> meetsCriteria(e, checkGroup)).count();
+ }
+
+ public boolean meetsCriteria(int input, boolean checkGroup)
+ {
+ int lastSeen = 10, current, adjacentTheSame = -2, skip = 10;
+
+ for (int i = 0; input > 0; i++) {
+ current = input % 10;
+ if(skip != current && current == lastSeen) {
+ if(checkGroup && adjacentTheSame+1 == i) {
+ adjacentTheSame = -2;
+ skip = current;
+ } else if(adjacentTheSame == -2) {
+ adjacentTheSame = i;
+ }
+ }
+ if (lastSeen < current)
+ return false;
+ lastSeen = current;
+ input /= 10;
+ }
+
+ return adjacentTheSame!=-2;
+ }
+
+ private int checkPasswords(boolean checkGroup) {
+ return Math.toIntExact(meetsCriteria(372037, 905157, checkGroup));
+ }
+
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
new file mode 100644
index 00000000..0e5b4006
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -0,0 +1,26 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day5 implements Day {
+
+ public static void main(String[] args) throws IOException {
+ new Day5().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ long res;
+ IntcodeComputer intcodeComputer = new IntcodeComputer(5, 1);
+ while((res = intcodeComputer.run()) == 0);
+ return res;
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return new IntcodeComputer(5, 5).run();
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
new file mode 100644
index 00000000..9a31e4ba
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -0,0 +1,80 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.ListMap;
+
+public class Day6 implements Day {
+
+ ListMap orbits = new ListMap<>();
+
+ public static void main(String[] args) throws IOException
+ {
+ new Day6().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ String[] nums = createOrbitArray();
+ for(String num : nums) {
+ String[] parts = num.split("\\)");
+ orbits.addTo(parts[0], parts[1]);
+ }
+ AtomicInteger o = new AtomicInteger();
+ for(var entry : orbits.entrySet())
+ countOrbitsInList(orbits, o, entry.getValue());
+ return o.get();
+ }
+
+ private void countOrbitsInList(ListMap orbits, AtomicInteger o, List entry) {
+ for(String str : entry) {
+ o.incrementAndGet();
+ if(orbits.containsKey(str)) {
+ countOrbitsInList(orbits, o, orbits.get(str));
+ }
+ }
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ return findRoute("YOU", "SAN");
+ }
+
+ private int findRoute(String from, String to) {
+ return findRoute(from, to, new ArrayList<>(), 0);
+ }
+
+ private int findRoute(String from, String to, List visited, int depth) {
+ if(visited.contains(from))
+ return 0;
+ visited.add(from);
+ List str = collectAll(from);
+ if(str.contains(to))
+ return depth-1;
+ for(String s : str) {
+ int findRoute = findRoute(s, to, visited, depth + 1);
+ if(findRoute>0) return findRoute;
+ }
+ return -1;
+ }
+
+ private List collectAll(String s1) {
+ List s = findOrbit(s1);
+ s.addAll(orbits.get(s1));
+ return s;
+ }
+
+ public List findOrbit(String orbitValue) {
+ return orbits.entrySet().stream().filter(e -> e.getValue().contains(orbitValue)).map(e -> e.getKey()).collect(Collectors.toList());
+ }
+
+ private String[] createOrbitArray() throws IOException {
+ return Arrays.stream(readDay(6).split(System.lineSeparator())).toArray(String[]::new);
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
new file mode 100644
index 00000000..433af6b0
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -0,0 +1,73 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day7 implements Day {
+
+ public static void main(String[] args) throws IOException {
+ new Day7().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ var permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
+ List results = new ArrayList<>();
+ for(List perm : permutations) {
+ long lastVal = 0;
+ for(Integer i : perm)
+ lastVal = new IntcodeComputer(7, i, lastVal).run();
+ results.add(lastVal);
+
+ }
+ return results.stream().mapToLong(e -> e).max().getAsLong();
+ }
+
+ @Override
+ public Object part2() throws IOException {
+ var permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
+ List results = new ArrayList<>();
+ perms: for(List shuffle : permutations) {
+ IntcodeComputer[] computers = new IntcodeComputer[5];
+ for(int i = 0; i e).max().getAsLong();
+ }
+
+ public List> generatePerm(List original) {
+ if (original.isEmpty()) {
+ List> result = new ArrayList<>();
+ result.add(new ArrayList());
+ return result;
+ }
+ E firstElement = original.remove(0);
+ List> returnValue = new ArrayList<>();
+ List> permutations = generatePerm(original);
+ for (List smallerPermutated : permutations) {
+ for (int index=0; index <= smallerPermutated.size(); index++) {
+ List temp = new ArrayList<>(smallerPermutated);
+ temp.add(index, firstElement);
+ returnValue.add(temp);
+ }
+ }
+ return returnValue;
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
new file mode 100644
index 00000000..c53be49f
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -0,0 +1,70 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.ProcessesImages;
+import com.sbaars.adventofcode2019.util.CountMap;
+
+public class Day8 implements Day, ProcessesImages {
+
+ private static final int DIM_X = 6;
+ private static final int DIM_Y = 25;
+ private static final int SIZE = DIM_X*DIM_Y;
+
+ public static void main(String[] args) throws IOException {
+ new Day8().printParts();
+ }
+
+ @Override
+ public Object part1() throws IOException {
+ int[] pixels = readPixels();
+ var pixelCounts = countPixels(pixels);
+ var cm = pixelCounts.stream().reduce((e1, e2) -> e1.get(0) > e2.get(0) ? e2 : e1).get();
+ return cm.get(1) * cm.get(2);
+ }
+
+ private int[] readPixels() throws IOException {
+ char[] chars = readDay(8).toCharArray();
+ return IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
+ }
+
+ private List> countPixels(int[] pixels) {
+ List> pixelCounts = new ArrayList<>();
+ for(int i = 0; i cm = new CountMap<>();
+ for(int j = i; j input = new ArrayDeque<>(2);
+ private long lastInput;
+ private long relativeBase = 0;
+ private static final int[] DO_NOT_TRANSFORM_FINAL_ARGUMENT = {1, 2, 3, 7, 8};
+ public static final long STOP_CODE = Long.MIN_VALUE+1;
+ private static final long CONTINUE_CODE = Long.MIN_VALUE;
+
+ public IntcodeComputer(int day, long...input) throws IOException {
+ this.program = Arrays.stream(readDay(day).split(",")).mapToLong(Long::parseLong).toArray();
+ this.program = Arrays.copyOf(this.program, 10000); // Quick hack to enlarge memory, should be refactored later(tm).
+ setInput(input);
+ if(day == 2) {
+ program[1] = input[0];
+ program[2] = input[1];
+ } else if(day == 17) {
+ program[0] = input[0];
+ }
+ }
+
+ public long run(long...input) {
+ setInput(input);
+ return run();
+ }
+
+ public long run() {
+ long result;
+ while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == CONTINUE_CODE);
+ return result;
+ }
+
+ private long executeInstruction(int instruction) {
+ if(instruction>99)
+ return parseComplexInstruction(instruction);
+ return execute(instruction);
+ }
+
+ private long execute(int instruction) {
+ return execute(new int[3], instruction);
+ }
+
+ private long execute(int[] method, int instruction) {
+ int nParams = nParams(instruction);
+ long[] args = IntStream.range(1, nParams+1).mapToLong(j -> program[instructionCounter+j]).toArray();
+ transformParameters(method, args, instruction);
+ return executeInstruction(args, instruction);
+ }
+
+ private void transformParameters(int[] method, long[] args, int instruction) {
+ IntStream.range(0, args.length).filter(i -> method[i] != 1).filter(i -> i+1 != args.length || !Arrays.stream(DO_NOT_TRANSFORM_FINAL_ARGUMENT).anyMatch(j -> j==instruction))
+ .forEach(i -> args[i] = program[Math.toIntExact((method[i] == 2 ? relativeBase : 0) + args[i])]);
+ if(Arrays.stream(DO_NOT_TRANSFORM_FINAL_ARGUMENT).anyMatch(j -> j==instruction) && method[args.length-1] == 2) {
+ args[args.length-1] += relativeBase;
+ }
+ }
+
+ private long readInput() {
+ if(input.isEmpty())
+ return lastInput;
+ lastInput = input.poll();
+ return lastInput;
+ }
+
+ public boolean addInput(long num) {
+ return input.add(num);
+ }
+
+ public long firstElement() {
+ return program[0];
+ }
+
+ public boolean setInput(long...input) {
+ this.input.clear();
+ return this.input.addAll(Arrays.stream(input).boxed().collect(Collectors.toList()));
+ }
+
+ private long executeInstruction(long[] args, int instruction) {
+ instructionCounter+=nParams(instruction) + 1;
+ switch(instruction) {
+ case 1: program[Math.toIntExact(args[2])] = args[0] + args[1]; break;
+ case 2: program[Math.toIntExact(args[2])] = args[0] * args[1]; break;
+ case 3: program[Math.toIntExact(args[0])] = readInput(); break;
+ case 4: return args[0];
+ case 5: if(args[0] != 0) instructionCounter = Math.toIntExact(args[1]); break;
+ case 6: if(args[0] == 0) instructionCounter = Math.toIntExact(args[1]); break;
+ case 7: program[Math.toIntExact(args[2])] = args[0] < args[1] ? 1 : 0; break;
+ case 8: program[Math.toIntExact(args[2])] = args[0] == args[1] ? 1 : 0; break;
+ case 9: relativeBase += Math.toIntExact(args[0]); break;
+ case 99: return STOP_CODE;
+ default: throw new IllegalStateException("Something went wrong!");
+ }
+ return CONTINUE_CODE;
+ }
+
+ private long parseComplexInstruction(int instruction) {
+ int[] instructions = getInstructions(instruction);
+ int opcode = getOpCode(instructions);
+ return execute(new int[] {instructions[2], instructions[1], instructions[0]}, opcode);
+ }
+
+ private int getOpCode(int instruction) {
+ return getOpCode(getInstructions(instruction));
+ }
+
+ private int getOpCode(int[] instructions) {
+ return (instructions[3] * 10) + instructions[4];
+ }
+
+ private int[] getInstructions(int instruction) {
+ int[] instructions = new int[5];
+ for(int j = instructions.length-1; instruction>0; j--) {
+ instructions[j] = instruction % 10;
+ instruction /= 10;
+ }
+ return instructions;
+ }
+
+ private int nParams(int instruction) {
+ switch(instruction) {
+ case 99: return -1;
+ case 3:
+ case 4:
+ case 9: return 1;
+ case 5:
+ case 6: return 2;
+ case 1:
+ case 2:
+ case 7:
+ case 8: return 3;
+ default: if(instruction>99) return nParams(getOpCode(instruction));
+ else throw new IllegalStateException("Something went wrong! "+instruction);
+ }
+ }
+
+ public void setElement(int i, long j) {
+ program[i] = j;
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
new file mode 100644
index 00000000..842824b3
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
@@ -0,0 +1,133 @@
+package com.sbaars.adventofcode2019.pathfinding;
+
+import java.awt.Point;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Creates nodes and neighbours from a 2d grid. Each point in the map has an
+ * integer value that specifies the cost of crossing that point. If this value
+ * is negative, the point is unreachable.
+ *
+ * If diagonal movement is allowed, the Chebyshev distance is used, else
+ * Manhattan distance is used.
+ *
+ * @author Ben Ruijl
+ *
+ */
+public class CharGrid2d {
+ private final char[][] map;
+ private final boolean allowDiagonal;
+ List collectedKeys;
+
+ /**
+ * A node in a 2d map. This is simply the coordinates of the point.
+ *
+ * @author Ben Ruijl
+ *
+ */
+ public class MapNode implements Node {
+ private final int x, y;
+
+ public MapNode(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public double getHeuristic(MapNode goal) {
+ if (allowDiagonal) {
+ return Math.max(Math.abs(x - goal.x), Math.abs(y - goal.y));
+ } else {
+ return Math.abs(x - goal.x) + Math.abs(y - goal.y);
+ }
+ }
+
+ public double getTraversalCost(MapNode neighbour) {
+ return 1 + map[neighbour.y][neighbour.x];
+ }
+
+ public Set getNeighbours() {
+ Set neighbours = new HashSet();
+
+ for (int i = x - 1; i <= x + 1; i++) {
+ for (int j = y - 1; j <= y + 1; j++) {
+ if ((i == x && j == y) || i < 0 || j < 0 || j >= map.length
+ || i >= map[j].length) {
+ continue;
+ }
+
+ if (!allowDiagonal &&
+ ((i < x && j < y) ||
+ (i < x && j > y) ||
+ (i > x && j > y) ||
+ (i > x && j < y))) {
+ continue;
+ }
+
+ if (map[j][i] == '#') {
+ continue;
+ }
+
+ // TODO: create cache instead of recreation
+ neighbours.add(new MapNode(i, j));
+ }
+ }
+
+ return neighbours;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result + x;
+ result = prime * result + y;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MapNode other = (MapNode) obj;
+ if (!getOuterType().equals(other.getOuterType()))
+ return false;
+ if (x != other.x)
+ return false;
+ if (y != other.y)
+ return false;
+ return true;
+ }
+
+ public Point toPoint() {
+ return new Point(x, y);
+ }
+
+ private CharGrid2d getOuterType() {
+ return CharGrid2d.this;
+ }
+
+ }
+
+ public CharGrid2d(char[][] map, boolean allowDiagonal) {
+ this.map = map;
+ this.allowDiagonal = allowDiagonal;
+ }
+
+ public List findPath(Point start, Point end) {
+ return PathFinding.doAStar(new MapNode(start.x, start.y), new MapNode(end.x, end.y)).stream().map(MapNode::toPoint).collect(Collectors.toList());
+ }
+
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
new file mode 100644
index 00000000..461e50f1
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
@@ -0,0 +1,134 @@
+package com.sbaars.adventofcode2019.pathfinding;
+
+import java.awt.Point;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.sbaars.adventofcode2019.days.Day15;
+
+/**
+ * Creates nodes and neighbours from a 2d grid. Each point in the map has an
+ * integer value that specifies the cost of crossing that point. If this value
+ * is negative, the point is unreachable.
+ *
+ * If diagonal movement is allowed, the Chebyshev distance is used, else
+ * Manhattan distance is used.
+ *
+ * @author Ben Ruijl
+ *
+ */
+public class Grid2d {
+ private final int[][] map;
+ private final boolean allowDiagonal;
+
+ /**
+ * A node in a 2d map. This is simply the coordinates of the point.
+ *
+ * @author Ben Ruijl
+ *
+ */
+ public class MapNode implements Node {
+ private final int x, y;
+
+ public MapNode(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public double getHeuristic(MapNode goal) {
+ if (allowDiagonal) {
+ return Math.max(Math.abs(x - goal.x), Math.abs(y - goal.y));
+ } else {
+ return Math.abs(x - goal.x) + Math.abs(y - goal.y);
+ }
+ }
+
+ public double getTraversalCost(MapNode neighbour) {
+ return 1 + map[neighbour.y][neighbour.x];
+ }
+
+ public Set getNeighbours() {
+ Set neighbours = new HashSet();
+
+ for (int i = x - 1; i <= x + 1; i++) {
+ for (int j = y - 1; j <= y + 1; j++) {
+ if ((i == x && j == y) || i < 0 || j < 0 || j >= map.length
+ || i >= map[j].length) {
+ continue;
+ }
+
+ if (!allowDiagonal &&
+ ((i < x && j < y) ||
+ (i < x && j > y) ||
+ (i > x && j > y) ||
+ (i > x && j < y))) {
+ continue;
+ }
+
+ if (map[j][i] == Day15.WALL || map[j][i] == Day15.UNEXPLORED) {
+ continue;
+ }
+
+ // TODO: create cache instead of recreation
+ neighbours.add(new MapNode(i, j));
+ }
+ }
+
+ return neighbours;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result + x;
+ result = prime * result + y;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MapNode other = (MapNode) obj;
+ if (!getOuterType().equals(other.getOuterType()))
+ return false;
+ if (x != other.x)
+ return false;
+ if (y != other.y)
+ return false;
+ return true;
+ }
+
+ public Point toPoint() {
+ return new Point(x, y);
+ }
+
+ private Grid2d getOuterType() {
+ return Grid2d.this;
+ }
+
+ }
+
+ public Grid2d(int[][] map, boolean allowDiagonal) {
+ this.map = map;
+ this.allowDiagonal = allowDiagonal;
+ }
+
+ public List findPath(Point start, Point end) {
+ return PathFinding.doAStar(new MapNode(start.x, start.y), new MapNode(end.x, end.y)).stream().map(MapNode::toPoint).collect(Collectors.toList());
+ }
+
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Node.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Node.java
new file mode 100644
index 00000000..d99e59f6
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Node.java
@@ -0,0 +1,40 @@
+package com.sbaars.adventofcode2019.pathfinding;
+import java.util.Set;
+
+/**
+ * A node in a graph, useful for pathfinding.
+ *
+ * @author Ben Ruijl
+ *
+ * @param
+ * Actual type of the node
+ */
+public interface Node {
+ /**
+ * The heuristic cost to move from the current node to the goal. In most
+ * cases this is the Manhattan distance or Chebyshev distance.
+ *
+ * @param goal
+ * @return
+ */
+ double getHeuristic(T goal);
+
+ /**
+ * The cost of moving from the current node to the neighbour. In most cases
+ * this is just the distance between the nodes, but additional terrain cost
+ * can be added as well (for example climbing a mountain is more expensive
+ * than walking on a road).
+ *
+ * @param neighbour
+ * Neighbour of current node
+ * @return Traversal cost
+ */
+ double getTraversalCost(T neighbour);
+
+ /**
+ * Gets the set of neighbouring nodes.
+ *
+ * @return Neighbouring nodes
+ */
+ Set getNeighbours();
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
new file mode 100644
index 00000000..7c13a084
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
@@ -0,0 +1,87 @@
+package com.sbaars.adventofcode2019.pathfinding;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+/**
+ * Helper class containing pathfinding algorithms.
+ *
+ * @author Ben Ruijl
+ *
+ */
+public class PathFinding {
+
+ /**
+ * A Star pathfinding. Note that the heuristic has to be monotonic:
+ * {@code h(x) <=
+ * d(x, y) + h(y)}.
+ *
+ * @param start
+ * Starting node
+ * @param goal
+ * Goal node
+ * @return Shortest path from start to goal, or null if none found
+ */
+ public static > List doAStar(T start, T goal) {
+ Set closed = new HashSet();
+ Map fromMap = new HashMap();
+ List route = new LinkedList();
+ Map gScore = new HashMap();
+ final Map fScore = new HashMap();
+ PriorityQueue open = new PriorityQueue(11, new Comparator() {
+
+ public int compare(T nodeA, T nodeB) {
+ return Double.compare(fScore.get(nodeA), fScore.get(nodeB));
+ }
+ });
+
+ gScore.put(start, 0.0);
+ fScore.put(start, start.getHeuristic(goal));
+ open.offer(start);
+
+ while (!open.isEmpty()) {
+ T current = open.poll();
+ if (current.equals(goal)) {
+ while (current != null) {
+ route.add(0, current);
+ current = fromMap.get(current);
+ }
+
+ return route;
+ }
+
+ closed.add(current);
+
+ for (T neighbour : current.getNeighbours()) {
+ if (closed.contains(neighbour)) {
+ continue;
+ }
+
+ double tentG = gScore.get(current)
+ + current.getTraversalCost(neighbour);
+
+ boolean contains = open.contains(neighbour);
+ if (!contains || tentG < gScore.get(neighbour)) {
+ gScore.put(neighbour, tentG);
+ fScore.put(neighbour, tentG + neighbour.getHeuristic(goal));
+
+ if (contains) {
+ open.remove(neighbour);
+ }
+
+ open.offer(neighbour);
+ fromMap.put(neighbour, current);
+ }
+ }
+ }
+
+ return new ArrayList<>();
+ }
+
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java b/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
new file mode 100644
index 00000000..5eb6543b
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
@@ -0,0 +1,58 @@
+package com.sbaars.adventofcode2019.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class CountMap extends HashMap {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public CountMap() {
+ }
+
+ public CountMap(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ public CountMap(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ public CountMap(Map extends K, Integer> m) {
+ super(m);
+ }
+
+ public Integer increment(K key) {
+ return super.put(key, super.containsKey(key) ? super.get(key) + 1 : 1);
+ }
+
+ public Integer increment(K key, int amount) {
+ return super.put(key, super.containsKey(key) ? super.get(key) + amount : amount);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Integer get(Object key){
+ if(!super.containsKey(key))
+ super.put((K) key, 0);
+ return super.get(key);
+ }
+
+ @Override
+ public String toString() {
+ return keySet().stream().sorted().map(e -> e+"\t"+get(e)).collect(Collectors.joining(System.lineSeparator()));
+ }
+
+ public void addAll(CountMap amountPerCloneClassSize) {
+ amountPerCloneClassSize.entrySet().stream().forEach(e -> this.increment(e.getKey(), e.getValue()));
+ }
+
+ public void incrementAll(CountMap input) {
+ for(Entry i : input.entrySet()) {
+ increment(i.getKey(), i.getValue());
+ }
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java b/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
index 3a90b468..289ee81c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
+++ b/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
@@ -4,58 +4,18 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
public interface DoesFileOperations {
public default String getFileAsString(File file) throws IOException {
- return new String(getFileBytes(file), StandardCharsets.UTF_8);
- }
-
- public default byte[] getFileBytes(File file) throws IOException {
- return Files.readAllBytes(file.toPath());
- }
-
- public default void writeStringToFile(File file, String content) throws IOException {
- if (file.exists())
- Files.delete(file.toPath());
- else if (file.getParentFile() != null)
- file.getParentFile().mkdirs();
- if (file.createNewFile())
- Files.write(Paths.get(file.getAbsolutePath()), content.getBytes(StandardCharsets.UTF_8));
+ return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
}
- public default void copyFolder(Path src, Path dest) {
- try {
- dest.toFile().mkdirs();
- Files.walk(src).forEach(source -> copy(source, dest.resolve(src.relativize(source))));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public default void copy(Path source, Path dest) {
- try {
- Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
+ public default String getResourceAsString(String resource) throws IOException {
+ return getFileAsString(new File(DoesFileOperations.class.getClassLoader().getResource(resource).getFile()));
}
- public default boolean delete(File dir) {
- if (dir.isDirectory()) {
- String[] children = dir.list();
- for (int i=0; i extends HashMap> {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public ListMap() {
+ }
+
+ public ListMap(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ public ListMap(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ public ListMap(Map extends K, ? extends List> m) {
+ super(m);
+ }
+
+ public List addTo(K key, V value) {
+ List l;
+ if(super.containsKey(key)) {
+ l = super.get(key);
+ } else l = new ArrayList<>();
+ l.add(value);
+ return super.put(key, l);
+ }
+
+ public List addTo(K key, V[] value) {
+ List l;
+ if(super.containsKey(key)) {
+ l = super.get(key);
+ } else l = new ArrayList<>();
+ Collections.addAll(l, value);
+ return super.put(key, l);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List get(Object key){
+ if(!super.containsKey(key))
+ super.put((K) key, new ArrayList<>());
+ return super.get(key);
+ }
+
+ public Entry> getEntryForValue(V i) {
+ System.out.println(Arrays.toString(values().toArray()));
+ Optional>> findAny = entrySet().stream().filter(e -> e.getValue().contains(i)).findAny();
+ if(!findAny.isPresent())
+ throw new IllegalAccessError("Value "+i+" does not exist in this map!");
+ return findAny.get();
+ }
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/LongCountMap.java b/src/main/java/com/sbaars/adventofcode2019/util/LongCountMap.java
new file mode 100644
index 00000000..1762fbf5
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/util/LongCountMap.java
@@ -0,0 +1,58 @@
+package com.sbaars.adventofcode2019.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class LongCountMap extends HashMap {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public LongCountMap() {
+ }
+
+ public LongCountMap(int initialCapacity, float loadFactor) {
+ super(initialCapacity, loadFactor);
+ }
+
+ public LongCountMap(int initialCapacity) {
+ super(initialCapacity);
+ }
+
+ public LongCountMap(Map extends K, Long> m) {
+ super(m);
+ }
+
+ public Long increment(K key) {
+ return super.put(key, super.containsKey(key) ? super.get(key) + 1 : 1);
+ }
+
+ public Long increment(K key, long amount) {
+ return super.put(key, super.containsKey(key) ? super.get(key) + amount : amount);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Long get(Object key){
+ if(!super.containsKey(key))
+ super.put((K) key, 0L);
+ return super.get(key);
+ }
+
+ @Override
+ public String toString() {
+ return keySet().stream().sorted().map(e -> e+"\t"+get(e)).collect(Collectors.joining(System.lineSeparator()));
+ }
+
+ public void addAll(LongCountMap amountPerCloneClassSize) {
+ amountPerCloneClassSize.entrySet().stream().forEach(e -> this.increment(e.getKey(), e.getValue()));
+ }
+
+ public void incrementAll(LongCountMap input) {
+ for(Entry i : input.entrySet()) {
+ increment(i.getKey(), i.getValue());
+ }
+ }
+}
diff --git a/src/main/resources/day1.txt b/src/main/resources/day1.txt
new file mode 100644
index 00000000..95bcbee3
--- /dev/null
+++ b/src/main/resources/day1.txt
@@ -0,0 +1,100 @@
+55131
+114008
+145297
+76135
+50317
+134036
+122136
+97704
+51245
+141732
+120427
+142020
+88166
+55313
+110391
+112436
+78195
+74294
+128984
+68240
+137098
+142016
+83577
+89257
+107744
+67357
+131342
+98247
+137501
+134577
+65696
+84925
+50159
+110319
+91921
+103303
+84505
+84683
+100811
+82626
+66774
+123216
+95151
+88237
+60705
+124319
+102926
+143160
+92780
+64283
+132434
+113935
+84907
+113698
+117240
+129327
+78837
+144841
+138054
+130990
+100191
+141768
+138941
+108165
+62138
+121690
+117305
+90147
+134422
+78031
+121331
+120947
+120235
+138880
+141076
+119480
+66844
+77660
+106364
+99187
+144244
+120483
+77715
+135703
+125521
+123253
+127556
+96458
+91965
+73924
+95176
+87540
+122083
+146013
+67761
+100413
+145994
+149450
+94330
+112824
\ No newline at end of file
diff --git a/src/main/resources/day10.txt b/src/main/resources/day10.txt
new file mode 100644
index 00000000..110bc35d
--- /dev/null
+++ b/src/main/resources/day10.txt
@@ -0,0 +1,39 @@
+.............#..#.#......##........#..#
+.#...##....#........##.#......#......#.
+..#.#.#...#...#...##.#...#.............
+.....##.................#.....##..#.#.#
+......##...#.##......#..#.......#......
+......#.....#....#.#..#..##....#.......
+...................##.#..#.....#.....#.
+#.....#.##.....#...##....#####....#.#..
+..#.#..........#..##.......#.#...#....#
+...#.#..#...#......#..........###.#....
+##..##...#.#.......##....#.#..#...##...
+..........#.#....#.#.#......#.....#....
+....#.........#..#..##..#.##........#..
+........#......###..............#.#....
+...##.#...#.#.#......#........#........
+......##.#.....#.#.....#..#.....#.#....
+..#....#.###..#...##.#..##............#
+...##..#...#.##.#.#....#.#.....#...#..#
+......#............#.##..#..#....##....
+.#.#.......#..#...###...........#.#.##.
+........##........#.#...#.#......##....
+.#.#........#......#..........#....#...
+...............#...#........##..#.#....
+.#......#....#.......#..#......#.......
+.....#...#.#...#...#..###......#.##....
+.#...#..##................##.#.........
+..###...#.......#.##.#....#....#....#.#
+...#..#.......###.............##.#.....
+#..##....###.......##........#..#...#.#
+.#......#...#...#.##......#..#.........
+#...#.....#......#..##.............#...
+...###.........###.###.#.....###.#.#...
+#......#......#.#..#....#..#.....##.#..
+.##....#.....#...#.##..#.#..##.......#.
+..#........#.......##.##....#......#...
+##............#....#.#.....#...........
+........###.............##...#........#
+#.........#.....#..##.#.#.#..#....#....
+..............##.#.#.#...........#.....
\ No newline at end of file
diff --git a/src/main/resources/day11.txt b/src/main/resources/day11.txt
new file mode 100644
index 00000000..7f841847
--- /dev/null
+++ b/src/main/resources/day11.txt
@@ -0,0 +1 @@
+3,8,1005,8,342,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1002,8,1,29,2,1006,19,10,1,1005,19,10,2,1102,11,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,1001,8,0,62,2,1009,15,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,1002,8,1,88,2,1101,6,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,114,1,105,8,10,1,1102,18,10,2,6,5,10,1,2,15,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,153,1,105,15,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,178,1,1006,15,10,1006,0,96,1006,0,35,1,104,7,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,214,1006,0,44,2,1105,17,10,1,1107,19,10,1,4,16,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,102,1,8,252,1006,0,6,1,1001,20,10,1006,0,45,2,1109,5,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,1,8,10,4,10,102,1,8,287,2,101,20,10,2,1006,18,10,1,1009,9,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,321,101,1,9,9,1007,9,1031,10,1005,10,15,99,109,664,104,0,104,1,21102,48210117528,1,1,21102,1,359,0,1105,1,463,21102,932700763028,1,1,21102,370,1,0,1105,1,463,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21102,1,179557207079,1,21102,417,1,0,1105,1,463,21102,1,28994202816,1,21101,0,428,0,1105,1,463,3,10,104,0,104,0,3,10,104,0,104,0,21101,0,709580710756,1,21102,1,451,0,1106,0,463,21102,825016201984,1,1,21101,462,0,0,1106,0,463,99,109,2,21201,-1,0,1,21102,40,1,2,21101,0,494,3,21102,1,484,0,1105,1,527,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,489,490,505,4,0,1001,489,1,489,108,4,489,10,1006,10,521,1101,0,0,489,109,-2,2105,1,0,0,109,4,1201,-1,0,526,1207,-3,0,10,1006,10,544,21102,1,0,-3,21202,-3,1,1,22102,1,-2,2,21102,1,1,3,21102,563,1,0,1105,1,568,109,-4,2106,0,0,109,5,1207,-3,1,10,1006,10,591,2207,-4,-2,10,1006,10,591,21202,-4,1,-4,1105,1,659,22102,1,-4,1,21201,-3,-1,2,21202,-2,2,3,21102,610,1,0,1106,0,568,21201,1,0,-4,21102,1,1,-1,2207,-4,-2,10,1006,10,629,21102,1,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,651,21202,-1,1,1,21102,1,651,0,106,0,526,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2106,0,0
\ No newline at end of file
diff --git a/src/main/resources/day12.txt b/src/main/resources/day12.txt
new file mode 100644
index 00000000..e637be38
--- /dev/null
+++ b/src/main/resources/day12.txt
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/day13.txt b/src/main/resources/day13.txt
new file mode 100644
index 00000000..a976d5d0
--- /dev/null
+++ b/src/main/resources/day13.txt
@@ -0,0 +1 @@
+1,380,379,385,1008,2235,768501,381,1005,381,12,99,109,2236,1102,0,1,383,1102,1,0,382,21002,382,1,1,20102,1,383,2,21102,1,37,0,1106,0,578,4,382,4,383,204,1,1001,382,1,382,1007,382,38,381,1005,381,22,1001,383,1,383,1007,383,21,381,1005,381,18,1006,385,69,99,104,-1,104,0,4,386,3,384,1007,384,0,381,1005,381,94,107,0,384,381,1005,381,108,1106,0,161,107,1,392,381,1006,381,161,1101,0,-1,384,1106,0,119,1007,392,36,381,1006,381,161,1101,0,1,384,20101,0,392,1,21102,1,19,2,21101,0,0,3,21102,138,1,0,1106,0,549,1,392,384,392,21002,392,1,1,21101,0,19,2,21101,3,0,3,21102,161,1,0,1106,0,549,1102,1,0,384,20001,388,390,1,21001,389,0,2,21101,180,0,0,1106,0,578,1206,1,213,1208,1,2,381,1006,381,205,20001,388,390,1,21001,389,0,2,21101,0,205,0,1106,0,393,1002,390,-1,390,1102,1,1,384,21002,388,1,1,20001,389,391,2,21101,0,228,0,1106,0,578,1206,1,261,1208,1,2,381,1006,381,253,21002,388,1,1,20001,389,391,2,21102,253,1,0,1106,0,393,1002,391,-1,391,1102,1,1,384,1005,384,161,20001,388,390,1,20001,389,391,2,21101,279,0,0,1105,1,578,1206,1,316,1208,1,2,381,1006,381,304,20001,388,390,1,20001,389,391,2,21101,0,304,0,1105,1,393,1002,390,-1,390,1002,391,-1,391,1102,1,1,384,1005,384,161,20102,1,388,1,20102,1,389,2,21101,0,0,3,21102,338,1,0,1105,1,549,1,388,390,388,1,389,391,389,21002,388,1,1,21002,389,1,2,21101,0,4,3,21101,0,365,0,1106,0,549,1007,389,20,381,1005,381,75,104,-1,104,0,104,0,99,0,1,0,0,0,0,0,0,320,17,16,1,1,19,109,3,21201,-2,0,1,22101,0,-1,2,21101,0,0,3,21102,414,1,0,1106,0,549,21202,-2,1,1,21201,-1,0,2,21102,1,429,0,1105,1,601,1201,1,0,435,1,386,0,386,104,-1,104,0,4,386,1001,387,-1,387,1005,387,451,99,109,-3,2106,0,0,109,8,22202,-7,-6,-3,22201,-3,-5,-3,21202,-4,64,-2,2207,-3,-2,381,1005,381,492,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,481,21202,-4,8,-2,2207,-3,-2,381,1005,381,518,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,507,2207,-3,-4,381,1005,381,540,21202,-4,-1,-1,22201,-3,-1,-3,2207,-3,-4,381,1006,381,529,22101,0,-3,-7,109,-8,2105,1,0,109,4,1202,-2,38,566,201,-3,566,566,101,639,566,566,1201,-1,0,0,204,-3,204,-2,204,-1,109,-4,2106,0,0,109,3,1202,-1,38,594,201,-2,594,594,101,639,594,594,20102,1,0,-2,109,-3,2106,0,0,109,3,22102,21,-2,1,22201,1,-1,1,21101,0,401,2,21102,1,733,3,21102,798,1,4,21102,1,630,0,1106,0,456,21201,1,1437,-2,109,-3,2105,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,0,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,2,0,1,1,0,2,2,0,2,0,2,2,2,2,0,2,2,2,2,2,0,2,0,2,2,0,2,2,2,2,0,0,2,2,2,0,2,0,2,0,1,1,0,0,2,2,2,0,0,2,0,2,2,0,2,2,2,2,0,0,2,0,2,2,2,2,2,2,2,0,2,0,2,2,2,0,2,0,1,1,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,0,0,2,0,2,0,2,2,0,2,2,0,2,2,2,2,2,0,2,0,1,1,0,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,0,2,0,2,2,0,0,2,2,0,2,2,2,0,1,1,0,2,2,2,2,0,2,0,0,2,2,2,0,2,2,2,0,2,0,2,0,0,2,2,2,0,2,2,2,0,0,2,0,2,2,0,1,1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,0,2,0,2,2,2,0,2,2,2,0,0,1,1,0,2,2,0,2,0,0,2,2,2,0,0,0,2,0,2,2,2,0,2,2,0,2,2,2,2,2,2,2,0,0,0,2,0,0,0,1,1,0,0,2,2,0,0,2,2,2,2,0,2,2,2,0,0,2,0,2,2,0,2,2,2,2,2,2,2,2,2,0,0,0,2,2,0,1,1,0,2,0,0,2,2,2,2,2,2,2,0,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,2,0,1,1,0,2,2,0,2,2,2,0,2,2,0,2,0,2,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,2,2,0,2,2,0,1,1,0,2,2,0,2,2,2,2,2,0,2,0,2,2,2,2,2,0,0,2,2,2,2,0,2,2,0,2,2,2,2,0,2,0,2,0,1,1,0,2,2,0,2,0,2,2,2,2,2,2,0,2,2,2,2,2,2,0,2,2,0,2,2,2,0,2,2,2,2,2,2,2,2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,25,47,80,47,44,8,60,70,40,60,9,9,88,82,66,91,81,11,3,95,72,53,39,7,33,48,69,45,31,75,6,61,77,72,25,57,70,2,92,78,46,43,88,74,45,27,94,73,90,43,68,90,22,64,2,5,3,40,98,62,25,95,74,1,35,2,1,54,76,68,88,75,30,77,35,40,43,49,85,55,53,12,77,94,89,9,55,8,50,82,7,89,21,85,37,48,4,33,1,28,97,62,95,41,14,22,52,24,72,2,25,51,32,55,36,73,84,22,66,69,36,1,57,97,50,21,98,41,36,59,56,6,80,46,2,86,14,67,77,59,77,5,13,97,98,83,83,42,10,62,64,86,97,17,90,37,27,54,40,39,61,38,11,67,40,65,13,6,85,71,9,93,69,9,28,48,7,93,67,95,90,15,29,90,88,8,75,64,36,42,29,92,24,28,19,4,19,60,16,1,97,43,50,13,10,82,30,19,86,32,93,46,32,66,94,91,44,39,57,51,48,41,92,17,97,16,92,41,92,58,31,94,82,68,25,10,32,98,24,77,17,5,82,30,16,40,82,67,14,16,33,3,96,72,90,83,97,4,55,69,8,30,29,2,47,8,47,52,41,2,14,67,7,57,14,4,94,44,47,9,81,54,91,50,85,41,84,45,65,33,66,28,35,98,89,92,57,81,49,89,89,39,11,8,97,77,12,30,33,77,12,46,64,37,2,84,34,11,54,23,33,57,40,27,95,47,3,17,8,43,15,13,13,41,80,62,93,68,45,82,86,17,44,49,51,29,9,92,67,14,81,16,97,5,65,6,85,46,35,19,50,88,51,23,90,35,44,74,33,36,13,20,44,42,71,51,32,60,22,29,13,26,1,64,26,75,86,43,78,4,43,41,52,67,16,20,63,37,60,2,1,53,37,75,55,3,40,66,36,1,69,18,55,33,81,38,1,81,24,80,31,25,79,30,84,83,71,72,11,94,62,6,35,15,9,63,29,27,76,33,62,77,47,12,61,84,13,38,73,11,32,49,87,6,25,57,87,4,35,91,67,19,30,72,59,79,46,64,66,14,21,15,85,25,22,45,87,96,90,28,83,72,29,71,58,14,50,71,48,19,50,78,63,65,3,41,64,82,50,64,74,77,93,21,52,55,24,34,19,61,19,13,44,80,38,53,36,41,96,17,77,9,84,87,79,51,77,35,5,55,82,23,63,20,66,68,23,92,81,10,2,57,97,4,24,44,28,25,56,4,22,61,11,35,60,75,63,96,60,94,3,65,93,63,28,54,21,10,20,12,46,15,84,93,43,83,71,90,52,48,33,47,32,75,22,22,38,8,62,42,30,95,66,15,75,14,73,17,10,94,64,70,29,51,70,14,68,56,60,57,9,84,16,77,37,17,44,37,22,88,60,85,59,61,52,3,21,15,19,23,90,33,47,36,48,44,30,33,16,22,37,93,78,16,43,18,65,18,61,67,71,51,13,33,7,48,40,70,9,66,12,59,49,67,34,23,51,75,48,23,30,47,23,81,21,42,6,66,34,4,67,45,21,90,34,48,47,43,11,3,54,9,10,35,60,78,19,17,68,1,9,26,92,7,86,66,13,12,31,12,71,55,43,78,39,54,70,62,38,93,25,89,83,37,37,2,60,87,84,48,98,43,1,78,86,97,67,41,85,66,17,23,32,9,35,91,4,18,89,71,4,88,66,50,32,92,9,44,10,23,31,17,53,36,46,94,33,93,68,44,85,73,72,14,34,69,66,77,43,93,23,24,14,17,79,27,63,7,44,95,66,55,83,8,90,58,43,768501
\ No newline at end of file
diff --git a/src/main/resources/day14.txt b/src/main/resources/day14.txt
new file mode 100644
index 00000000..46da9f07
--- /dev/null
+++ b/src/main/resources/day14.txt
@@ -0,0 +1,60 @@
+11 BNMWF, 1 MRVFT, 10 PBNSF => 7 XSFVQ
+149 ORE => 4 SMSB
+1 XHQDX, 1 SVSTJ, 2 LDHX => 7 JMWQG
+12 MJCLX => 9 PBNSF
+132 ORE => 7 XPTXL
+15 TZMWG, 1 LDHX, 1 PDVR => 7 LBQB
+1 HJTD, 8 VFXHC => 2 SVSTJ
+5 LBHQ, 6 MTQCB => 4 MHBZ
+1 PRXT, 1 FWZN => 2 PBMPL
+1 XPTXL => 1 HMRGM
+10 XHPHR => 6 NSVJL
+3 QZQLZ, 3 MTQCB => 4 TZMWG
+5 LBHQ, 2 VPSDV => 3 ZFCD
+13 WPFP => 6 ZXMGK
+10 MHJMX, 75 LDHX, 52 JMWQG, 4 QWRB, 1 SVNVJ, 17 BNMWF, 18 GHVN => 1 FUEL
+4 PFQRG, 14 XVNL => 5 PDCV
+11 JMWQG, 10 ZBNCP => 6 NTJZH
+14 PBMPL, 12 PRXT, 9 MJQS => 9 XVNL
+9 GDNG, 13 LBQB => 9 QWRB
+1 CXNM => 6 PFQRG
+9 NTJZH, 7 BNMWF, 11 JCHP, 1 MHBZ, 1 SVSTJ, 9 XRDN => 5 SVNVJ
+1 XHPHR, 1 GSMP => 4 THRVR
+26 FWZN => 4 WPFP
+35 VJTFJ, 2 XSFVQ, 6 HJVN, 1 NSVJL, 1 JCHP, 3 MJCLX, 1 QZNCK => 6 GHVN
+1 WPFP, 3 XHPHR => 2 HJVN
+5 SMSB => 7 HNCDS
+111 ORE => 4 GSMP
+6 LBHQ => 8 GDNG
+2 GDNG, 5 MHBZ => 1 RNMKC
+15 THRVR, 4 NWNSH, 1 NSVJL => 7 FDVH
+2 HMRGM => 9 FWZN
+6 MJQS, 5 JRZXM => 5 NWNSH
+14 ZXMGK, 1 JTXWX => 6 DLWT
+1 MJQS, 3 FWZN, 2 PRXT => 1 JTXWX
+1 GSMP, 4 CXNM => 3 JRZXM
+151 ORE => 9 ZNPRL
+2 NTJZH, 1 DLWT, 3 ZBNCP => 9 MRVFT
+14 SWZCB, 1 VPSDV => 7 XRDN
+14 LBHQ, 16 FDVH, 9 PFQRG => 4 PRXT
+22 CXNM => 9 HJTD
+1 VFXHC, 1 MTQCB => 6 QZQLZ
+6 SWZCB, 2 PDCV, 17 RNMKC => 9 LTHFW
+4 ZNPRL => 6 CXNM
+2 CXNM => 3 LBHQ
+8 MHBZ, 2 QZQLZ, 2 LBQB => 3 VJTFJ
+3 ZFCD => 1 XHQDX
+1 VJTFJ, 7 MHBZ => 8 ZBNCP
+5 CXNM => 2 VPSDV
+7 MJQS => 9 VFXHC
+2 LTHFW, 11 HJVN, 4 XRDN, 8 MRVFT, 3 NSVJL, 3 SVSTJ, 5 XSFVQ, 13 RNMKC => 8 MHJMX
+2 HMRGM => 3 XHPHR
+1 GDNG, 19 PDVR => 3 SWZCB
+18 HMRGM, 10 HNCDS => 2 MJQS
+6 HNCDS, 2 HMRGM, 1 LBHQ => 3 MTQCB
+16 VJTFJ, 1 WPFP, 6 JMWQG => 6 BNMWF
+3 TZMWG, 1 FWZN => 7 PDVR
+10 ZXMGK => 4 QZNCK
+32 LBQB, 1 ZBNCP => 1 JCHP
+27 PDVR, 7 QZQLZ, 7 PBMPL => 3 MJCLX
+5 MHBZ, 12 ZFCD => 4 LDHX
\ No newline at end of file
diff --git a/src/main/resources/day15.txt b/src/main/resources/day15.txt
new file mode 100644
index 00000000..0af98421
--- /dev/null
+++ b/src/main/resources/day15.txt
@@ -0,0 +1 @@
+3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,101,0,1034,1039,1001,1036,0,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,101,0,1034,1039,101,0,1036,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1106,0,124,1001,1034,-1,1039,1008,1036,0,1041,1001,1035,0,1040,1001,1038,0,1043,1002,1037,1,1042,1105,1,124,1001,1034,1,1039,1008,1036,0,1041,102,1,1035,1040,101,0,1038,1043,1002,1037,1,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,1,1032,1006,1032,165,1008,1040,33,1032,1006,1032,165,1101,0,2,1044,1106,0,224,2,1041,1043,1032,1006,1032,179,1101,1,0,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,43,1044,1105,1,224,1101,0,0,1044,1106,0,224,1006,1044,247,1002,1039,1,1034,1002,1040,1,1035,102,1,1041,1036,1001,1043,0,1038,101,0,1042,1037,4,1044,1105,1,0,13,30,60,64,5,28,36,24,67,12,1,67,32,39,14,78,29,17,38,88,79,9,62,25,15,18,88,25,7,81,38,41,10,69,86,32,11,33,1,10,22,84,14,92,48,79,10,3,62,33,61,13,93,78,20,63,68,17,80,34,12,8,23,61,90,51,17,84,37,46,64,25,3,73,19,45,99,41,62,21,77,8,17,89,9,13,84,75,85,14,53,60,6,29,76,63,14,23,63,61,93,72,17,41,28,94,5,3,19,47,57,55,14,34,38,79,85,40,13,22,99,67,72,15,62,15,6,63,3,90,2,87,20,84,15,50,70,27,18,78,21,70,48,52,2,99,92,55,3,46,41,93,99,88,13,39,4,45,71,3,96,1,91,59,31,53,23,25,82,32,50,16,60,38,78,34,59,30,15,51,92,3,22,26,62,60,37,42,74,28,21,76,7,24,70,18,40,11,81,41,9,73,62,12,66,81,9,3,74,62,11,6,56,16,34,20,78,79,1,97,17,39,87,15,12,77,94,28,22,66,45,59,39,2,6,52,6,72,49,17,92,15,86,18,92,79,67,20,22,72,10,72,3,52,26,77,78,41,97,36,59,88,24,57,12,38,90,53,14,38,67,2,36,44,93,99,10,41,49,3,16,7,63,32,11,15,81,12,91,39,62,19,83,6,91,28,19,80,38,23,63,31,71,14,58,8,21,71,21,21,81,38,26,32,29,82,52,28,72,54,97,41,65,96,75,1,48,28,80,66,25,47,49,29,87,51,12,50,70,36,60,81,29,77,76,55,25,40,45,83,91,26,72,99,12,47,11,20,27,52,9,98,17,99,27,37,62,25,3,15,73,66,22,5,85,5,20,98,20,38,62,78,21,16,59,28,98,38,31,2,40,46,87,14,48,33,80,48,36,27,56,21,1,50,83,3,61,92,20,52,16,50,10,86,9,98,39,56,25,50,42,39,91,81,56,25,70,44,24,15,99,4,20,55,12,98,27,65,20,77,97,76,36,42,87,6,11,79,65,16,65,44,13,90,13,48,79,13,95,60,19,55,24,66,4,53,11,23,68,14,97,53,45,14,16,93,18,29,83,5,6,77,19,70,97,34,20,70,52,11,74,14,72,10,36,44,33,45,19,38,36,77,5,37,51,1,55,17,2,48,23,18,2,34,90,97,24,30,51,66,33,70,51,37,31,51,37,65,55,18,8,66,4,65,62,26,93,29,88,3,75,73,24,23,67,1,13,68,7,36,87,62,48,1,31,45,28,62,86,24,98,1,59,49,37,26,62,36,44,66,18,17,97,92,40,36,65,80,84,5,84,6,79,87,36,31,96,15,71,96,2,72,11,81,95,94,41,54,31,58,25,74,24,51,81,38,32,73,22,96,40,62,22,59,74,39,25,86,2,55,20,61,40,37,88,69,1,60,42,18,31,54,13,27,19,93,34,41,99,33,89,20,16,52,84,32,94,31,6,61,25,1,61,1,38,78,87,39,31,39,26,68,42,36,2,94,66,2,67,30,80,2,95,65,40,54,50,33,11,23,97,89,1,31,56,9,35,49,92,55,23,84,48,91,20,7,72,25,55,3,85,3,16,40,90,22,99,44,38,86,98,11,76,26,76,13,82,80,24,93,4,15,64,95,58,15,85,25,57,29,66,3,66,19,98,57,24,44,59,35,76,48,31,92,33,94,68,56,41,45,15,46,5,68,15,65,34,73,49,68,17,78,28,80,24,59,26,74,21,52,1,94,5,61,41,88,37,56,1,49,0,0,21,21,1,10,1,0,0,0,0,0,0
\ No newline at end of file
diff --git a/src/main/resources/day16.txt b/src/main/resources/day16.txt
new file mode 100644
index 00000000..1101f127
--- /dev/null
+++ b/src/main/resources/day16.txt
@@ -0,0 +1 @@
+59773419794631560412886746550049210714854107066028081032096591759575145680294995770741204955183395640103527371801225795364363411455113236683168088750631442993123053909358252440339859092431844641600092736006758954422097244486920945182483159023820538645717611051770509314159895220529097322723261391627686997403783043710213655074108451646685558064317469095295303320622883691266307865809481566214524686422834824930414730886697237161697731339757655485312568793531202988525963494119232351266908405705634244498096660057021101738706453735025060225814133166491989584616948876879383198021336484629381888934600383957019607807995278899293254143523702000576897358
\ No newline at end of file
diff --git a/src/main/resources/day17.txt b/src/main/resources/day17.txt
new file mode 100644
index 00000000..4b95b77f
--- /dev/null
+++ b/src/main/resources/day17.txt
@@ -0,0 +1 @@
+1,330,331,332,109,3564,1102,1182,1,15,1101,0,1449,24,1002,0,1,570,1006,570,36,101,0,571,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,15,1,15,1008,15,1449,570,1006,570,14,21102,58,1,0,1105,1,786,1006,332,62,99,21101,333,0,1,21102,1,73,0,1106,0,579,1101,0,0,572,1102,1,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,1001,574,0,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21102,340,1,1,1106,0,177,21102,477,1,1,1105,1,177,21101,0,514,1,21101,176,0,0,1106,0,579,99,21102,1,184,0,1105,1,579,4,574,104,10,99,1007,573,22,570,1006,570,165,102,1,572,1182,21102,375,1,1,21102,1,211,0,1106,0,579,21101,1182,11,1,21102,222,1,0,1105,1,979,21101,388,0,1,21101,233,0,0,1105,1,579,21101,1182,22,1,21102,1,244,0,1105,1,979,21102,1,401,1,21102,255,1,0,1105,1,579,21101,1182,33,1,21102,1,266,0,1106,0,979,21102,1,414,1,21102,1,277,0,1105,1,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21102,1,1182,1,21101,313,0,0,1105,1,622,1005,575,327,1102,1,1,575,21102,1,327,0,1105,1,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,36,16,0,109,4,1202,-3,1,586,21001,0,0,-1,22101,1,-3,-3,21102,0,1,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1105,1,597,109,-4,2105,1,0,109,5,2102,1,-4,629,21002,0,1,-2,22101,1,-4,-4,21101,0,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21001,0,0,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21102,1,702,0,1106,0,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21102,731,1,0,1106,0,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21102,756,1,0,1106,0,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1105,1,622,21201,-3,1,-3,1106,0,640,109,-5,2106,0,0,109,7,1005,575,802,20102,1,576,-6,20102,1,577,-5,1105,1,814,21101,0,0,-1,21101,0,0,-5,21101,0,0,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,45,-3,22201,-6,-3,-3,22101,1449,-3,-3,1201,-3,0,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1106,0,924,1205,-2,873,21101,0,35,-4,1106,0,924,1201,-3,0,878,1008,0,1,570,1006,570,916,1001,374,1,374,2102,1,-3,895,1102,2,1,0,2102,1,-3,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,921,21002,0,1,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,45,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,47,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21101,0,973,0,1105,1,786,99,109,-7,2106,0,0,109,6,21102,1,0,-4,21101,0,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1106,0,1041,21101,0,-4,-2,1105,1,1041,21102,-5,1,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1201,-2,0,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,2101,0,-2,0,1105,1,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1106,0,989,21102,1,439,1,1105,1,1150,21101,0,477,1,1105,1,1150,21102,1,514,1,21101,1149,0,0,1105,1,579,99,21102,1157,1,0,1106,0,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,2101,0,-5,1176,1201,-4,0,0,109,-6,2105,1,0,36,9,36,1,7,1,36,1,7,1,36,1,7,1,24,7,5,1,7,1,24,1,5,1,5,1,7,1,24,1,5,1,1,13,24,1,5,1,1,1,3,1,32,1,5,1,1,1,3,7,26,1,5,1,1,1,9,1,26,1,5,1,1,1,9,1,26,1,5,1,1,1,9,1,26,9,9,1,32,1,11,1,32,1,11,1,32,1,11,1,32,7,5,1,44,1,44,1,44,1,36,9,36,1,22,9,13,1,22,1,7,1,13,1,20,13,9,7,16,1,1,1,7,1,1,1,9,1,1,1,3,1,10,5,1,1,1,1,7,1,1,1,9,1,1,1,3,1,10,1,3,1,1,1,1,1,7,1,1,1,9,1,1,1,3,1,6,13,7,1,1,1,3,5,1,1,1,5,6,1,3,1,3,1,1,1,9,1,1,1,3,1,3,1,1,1,12,1,3,7,9,13,12,1,7,1,13,1,3,1,3,1,14,1,7,1,13,9,14,1,7,1,17,1,18,9,17,7,44,1,44,1,44,1,42,9,38,1,5,1,38,1,5,1,38,1,5,1,38,1,5,1,38,1,5,1,38,1,5,1,38,1,5,1,38,7,6
\ No newline at end of file
diff --git a/src/main/resources/day18.txt b/src/main/resources/day18.txt
new file mode 100644
index 00000000..9200145e
--- /dev/null
+++ b/src/main/resources/day18.txt
@@ -0,0 +1,81 @@
+#################################################################################
+#.......#.A...........#.........#.......#.#.........#.............#...#..r......#
+#.###.###.#####.#####.#.#######.#.#######.#.#.#####.#.#.#.#######.###.#.###.###.#
+#...#.#...#.....#.#...#...#.....#.......#...#.#...#o#.#.#.#...#.#...#.#...#.#...#
+#####.#.###.#####.#.###.#W###.#########.#####.#.#.###.#.#.#.#.#.###.#K###.#.#####
+#.....#.#.#...#...#...#.#...#...........#...#...#.....#.#.#.#.#.#...#...#.#.....#
+#M###.#.#.###.#.#####.#####.###########.#.#.###.#######.###.#.#.#.#####.#.#####.#
+#.#...#...#...#.#...#.....#...#..z....#.#.#...#...#.....#...#.#.#.#...#.......#.#
+#.###.###.#.###.#.#.#####.###.#.###.#.#.#.###.#####.#.###.###.#.#.#.#.#####.###.#
+#...#...#.#.#....y#.....#.....#.#.#.#.#.#...#.#...#.#.#...#...#.#...#.#...#.#m..#
+#.#.#####.#.###########.#######.#.#.#.#.###.#.#.#X#.#.#.###.###.#####.#.#.###.###
+#.#.#...#.#s..#.......#.......#...#.#.#.#...#...#.#.#.#.#.#.#.......#...#...#...#
+###.#.#.#.###.#.#####.###.###.#####.#.#.#.#######.#.###.#.#.#.#####.#######.###.#
+#...#.#...#.#...#...#.#...#.......#.#.#.#.#.......#.....#.#.#.#.....#.....#.....#
+#.###.#####.#####.#.#C#.###.#####.#.#.#.#.#####.###.#####.#.###.#####.#.#.#####.#
+#.....#.....#.....#.#.#.#...#...#...#.#.#.#.F.#...#...#...#...#.#...#.#.#.....#.#
+#.#######.#.###.###.#.#.#####.#.#######.#.#.#.###.###.###.###.#.#.#.#.#.#######.#
+#.#.......#...#.#...#.#...#...#.#.......#...#.#.#...#.......#.#.#.#.#.#.........#
+#.#.#########.#.#####.###N#.###.#.###########.#.###.#########.#.#.#.#.###########
+#...#...#.......#.....#...#.#.#.#.......#...#.#...............#...#.#.#....q....#
+#####.###.#######.#####.###.#.#.#######.#.#.#.#############.#####.#.#.#.#.#####.#
+#g..#.....#.....#...#.#...#...#.......#.#.#.#..l..........#.#...#.#.#.#.#...#...#
+###.#.#####.###.###.#T#.#.###.###.#####.###.#############.#####B#.#.#.#.###.#####
+#...#.#...#...#.....#.#.#...#.#.#.#...#.#.......#.......#...#...#.#...#...#.....#
+#.###.###.###.#####.#.###.###.#.#.#.#.#.#.#####.#.###.#####.#.###.#####.#######.#
+#...#...#...#.#.#...#...#.I...#.#...#...#.....#.#...#.#...#...#.#...#.#.#.......#
+###.###.#.###.#.#.#####.#####.#.#############.#####.#.#.#.#####.###.#.#.#.#######
+#.....#.#...#.#.......#.#...#...........#.....#.....#...#.......#.#.#.#.#.......#
+#.#####.###.#.#######.#.#.#.#####.#######.###.#.###########.###.#.#.#.#.#######.#
+#...........#.#e....#.#...#...#...#.....#.#...#...#.........#.....#.#...#.......#
+#.###########.#.###.#########.#####.###.#.#######.#.#####.#######.#.#####.#####.#
+#.....#.#.....#.#.#.........#.......#...#.#.......#.#.....#.....#.#...#...#.#...#
+#####.#.#.#####.#.#####.#.###########.###.#.#######.#####.#.###.#.###.#.###.#.###
+#...#.#.#.......#.#.....#.#.........#.#.#...#.#.....#...#.#.#...#...#.#...#...#.#
+#.###.#.#########.#.#####.#V#.#####.#.#.#.###.#.###.#.#.###.#.#######.###.#.###.#
+#.#...#.....#.....#.#.....#.#...#...#.#.#.#...#.#.#.#.#.....#.........#...#.#...#
+#.#.###.###.#.#####.#######.###.#.###.#.#.###.#.#.#.#.#################.###.#.#.#
+#.#.....#.#.#.....#.......#.#.#.#...#.#.#.#...#.#...#.#.........#.......#.S.#.#.#
+#.#######.#.#####.#######.#.#.#.#####.#.#.#.#.#.#####.#####.###.#.#######.###.#.#
+#.......................#.....#.............#.#.............#.....#...........#.#
+#######################################.@.#######################################
+#...............#.....#.....#.............#.........................D.......#..u#
+#.#############.#####.#.#.###.###.#####.#.#.#.#####.#######.###############.#.###
+#.....#.....#...#...#...#.....#.#.#.....#...#....v#.#.....#.#.......#.....#.#.E.#
+#####.#.#####.###.#.#.#########.#.#######.#######.###.###.###.#####.#.#####.#.#.#
+#.....#.....#.....#.#.#...#.....#.......#.#.......#.....#.#...#...#.#....j#t#.#.#
+#.#########.#######.#.#.#.#.###########.#.#.#######.#####.#.###.###.#####.#.#.#.#
+#.......#...#...#...#...#...#.......#...#.#.#.....#.#.....#.#.....#.#...#.#.#.#.#
+#######.#.#.###.#.#######.###.#####.#.#####.#.###.#.#.#####.#####.#.#.#.#.#.###.#
+#.....#.#.#.....#...#.....#...#.....#...#...#.#.#...#.....#.......#...#.#.#.#...#
+###.###.#.#####.###.#####.#.###.#####.#.#.#.#.#.#########.#######.#####.#.#.#.#.#
+#...#...#...#...#.#.....#.#.#.#.#.....#.#.#d#.#.....#.......#.....#.....#.#...#.#
+#.###.#####.#.###.#####.#.#.#.#.#######.#.###.###.#.#.#######.#####.#####.#####.#
+#.....#...#.#.....#.....#.#.#.#...#.....#.....#...#.#.....#.....#...#...#.....#.#
+#.#####.#.#.#.#####.#####.#.#.###.#.###.#######.#.#######.#.#####.#####.#.#.#.#.#
+#.#.....#.#.#.#.....#.....#.#...#.#.#...#.......#.#.....#...#.#...#.....#.#.#.#.#
+#.###.#.#.#.#.#.###########.###.#.#.#.###.#########.#.#######.#.#####.###.#.###.#
+#.H.#.#.#.#.#.#.....#.....#.#...#...#...#.#.....#...#.........#.#.....#...#.....#
+###.###.#.#.#.#####.#.###.#.#.#########.#.#.###.#.#######.#####.#.#.#.#.#########
+#.#.#...#...#...#.#...#...#.#...#.......#...#.#...#.....#...#...#.#.#.#.........#
+#.#.#.#.#######.#.#####.###.#.#.#.#######.###.#########.###.#.#####.#.#########.#
+#...#.#.#...#.#.#...#...#...#.#.#...#...#...#...#.....#...#.#.#.....#.#.......#.#
+#.###.###.#.#.#.###.#######.#.#.###.#.#.###.#.###.#.#.#.#.#.###.#####.###.###.#.#
+#.#...#...#.#.#.#...........#.#...#.#.#.#.#.#.#...#.#...#.#.....#...#...#.#.#.#.#
+#.###.#.###.#.#.#.###########.###.#.#.#.#.#.#.#.###.#####.#####.###.###.#.#.#.#.#
+#...#...#.#.#.#...#...#.U...#.#.#...#.#.#...#.....#.#.....#...#...#...#...#...#.#
+###.#.###.#.#.#####J#.#.#.###.#.#####.###.#######.#.#####.#.#####.#.#####.#####.#
+#...#.Q.#.#.#.....#.#...#.....#.........#.......#.#f....#.L.#.....#h....#.#...#.#
+#.#####.#.#.###.#.#.#################.#.#######.#.#####.###.#.#####.#.###.#.#.#.#
+#.#...#...#...#.#.#.#...#.......#...#.#.#.#...G.#.....#.Z.#.#...#...#.....#.#...#
+#.#.#####.###.###.#.#.#.#####.#.#.#.###.#.#.#############.#.###.#########.#.#####
+#k#.#.....#.#...#.#..c#...#...#...#.#...#.#.#........n#...#...#.#.......#.#...#.#
+#.#.#.#####.###.#.#######.#.#######.#.#.#.#.#.#######.#.###.###.#.#####.#####.#.#
+#.#...#.....#...#.#.P...#.#.#.....#...#.#.#.#.#...#...#.#...#...#.....#.....#p..#
+#.###.#.#.###.###.#.#.###.#.###.#.#####.#.#.#.#.###.###.###.#.#######.###.#####.#
+#...#...#.#...#.#...#...#.#...#.#...#...#.O.#.#.....#.#...#b#.#.......#.#.#...#.#
+###.#####.#.###.#.#####.#.###.#####.#.###.###.#.#####.#.#.###.#.#######.#.#.#.#.#
+#.#.#.....#.#a..#.#...#.#.#...#.....#...#...#i#.#...#...#.Y.#.#.#....w..#.#.#...#
+#.#R#######.#.#.#.###.#.#.#.###.#######.###.#.#.#.#.#######.#.#.#####.#.#.#.#####
+#...........#.#.......#.....#...........#.....#x..#.........#.........#.#.......#
+#################################################################################
\ No newline at end of file
diff --git a/src/main/resources/day19.txt b/src/main/resources/day19.txt
new file mode 100644
index 00000000..4bdbeb34
--- /dev/null
+++ b/src/main/resources/day19.txt
@@ -0,0 +1 @@
+109,424,203,1,21102,11,1,0,1105,1,282,21101,0,18,0,1105,1,259,2101,0,1,221,203,1,21102,1,31,0,1105,1,282,21102,1,38,0,1105,1,259,20102,1,23,2,21201,1,0,3,21102,1,1,1,21102,57,1,0,1106,0,303,2102,1,1,222,21002,221,1,3,20101,0,221,2,21101,0,259,1,21101,0,80,0,1105,1,225,21101,44,0,2,21102,91,1,0,1105,1,303,1202,1,1,223,21002,222,1,4,21102,259,1,3,21102,1,225,2,21102,225,1,1,21101,118,0,0,1106,0,225,21002,222,1,3,21101,163,0,2,21101,0,133,0,1106,0,303,21202,1,-1,1,22001,223,1,1,21102,148,1,0,1106,0,259,1202,1,1,223,20101,0,221,4,21001,222,0,3,21102,1,24,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21101,195,0,0,105,1,108,20207,1,223,2,21002,23,1,1,21102,-1,1,3,21102,1,214,0,1106,0,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2101,0,-4,249,22102,1,-3,1,22101,0,-2,2,22101,0,-1,3,21102,250,1,0,1106,0,225,21202,1,1,-4,109,-5,2105,1,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22102,1,-2,-2,109,-3,2105,1,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,21202,-2,1,3,21101,0,343,0,1106,0,303,1106,0,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21201,-4,0,1,21101,384,0,0,1105,1,303,1105,1,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21202,1,1,-4,109,-5,2105,1,0
\ No newline at end of file
diff --git a/src/main/resources/day2.txt b/src/main/resources/day2.txt
new file mode 100644
index 00000000..b61b8381
--- /dev/null
+++ b/src/main/resources/day2.txt
@@ -0,0 +1 @@
+1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,6,19,23,2,23,6,27,1,5,27,31,1,31,9,35,2,10,35,39,1,5,39,43,2,43,10,47,1,47,6,51,2,51,6,55,2,55,13,59,2,6,59,63,1,63,5,67,1,6,67,71,2,71,9,75,1,6,75,79,2,13,79,83,1,9,83,87,1,87,13,91,2,91,10,95,1,6,95,99,1,99,13,103,1,13,103,107,2,107,10,111,1,9,111,115,1,115,10,119,1,5,119,123,1,6,123,127,1,10,127,131,1,2,131,135,1,135,10,0,99,2,14,0,0
\ No newline at end of file
diff --git a/src/main/resources/day20.txt b/src/main/resources/day20.txt
new file mode 100644
index 00000000..b93543d5
--- /dev/null
+++ b/src/main/resources/day20.txt
@@ -0,0 +1,107 @@
+ L S F Z O X Q W
+ T S P Z J J X L
+ #############################.#######.#####.#.#####.#####.#####.#####.#################################
+ #.#.....#.....#.#.#.#.....#.....#.#.......#...#.....#.#...#.#.#.#.......#...#.#.#...#.#...#.#...#.#.#.#
+ #.###.#.###.###.#.#.###.#####.###.###.#.#####.###.###.#.###.#.#.#####.###.#.#.#.#.###.#.###.#.#.#.#.#.#
+ #.....#.#...#.#.....#.#...#.....#.#.#.#.#...#.#.....#.......#...#...#.....#.#.............#.#.#.....#.#
+ #######.###.#.#.#####.###.#.#####.#.###.#.#.#.#####.#.#.#.#.#.#.#.###.#####.#.#.#########.#.#.#######.#
+ #...#.....#.....#...#.........#.......#.#.#.....#...#.#.#.#.#.#.#...#.#.......#.........#.......#.....#
+ #.#######.#####.###.#########.###.###.#.#.#######.#.###.###.###.###.#.#.#####.#.#####.#.#.#.#######.###
+ #.#...#.....#.......#.#.#.#...#...#...#.#...#...#.#...#...#.#.....#...#.....#.#.....#.#.#.#.#.#.#.....#
+ #.#.#####.#.###.###.#.#.#.#.#####.###.#.#.###.#####.#.#.#######.#####.#####.###########.###.#.#.#.###.#
+ #...#...#.#.......#...........#.....#.#.#...#...#...#.#.....#...#.....#...#.#.....#...#.#.#.#.....#.#.#
+ ###.#.#######.#############.#######.#.#.###.#.#####.#.#.#.###.#.#######.#.#.#.###.###.###.#####.###.###
+ #.........#.#.#.....#...#.......#...#...#.......#...#.#.#.#.#.#.....#...#.......#.#.......#.....#...#.#
+ #.###.###.#.#.#####.###.###.#####.###.#.###.#.#######.#.###.###.#.#.#.#.#.###.###.###.#####.###.#.###.#
+ #.#...#.........#...............#.#...#.#...#...#.....#...#...#.#.#.#.#.#...#.#.......#.#.#...#...#...#
+ ###.#######.#.#####.###.###.#####.#######.###########.#.###.###.#####.#################.#.#.#####.###.#
+ #.#...#.....#.....#...#.#.....#.......#.#...#.........#.....#.#.....#...........#.#.#.#...#.#.#.#.#...#
+ #.#######.###.#.###########.#########.#.###.###.###.#######.#.###.###.#.###.#####.#.#.#.#.###.#.#.#.###
+ #.#...#.#.#...#...#.............#.......#.....#...#...#.......#...#...#.#...#.#...#.#...#...#.#.#...#.#
+ #.###.#.#####.#####.#######.###.###.#####.###########.###.#####.#####.#######.#.###.###.#####.#.#.###.#
+ #.#.........#.....#.#.....#.#.....#.....#...#.#.....#.#.......#...#.#...........#.#.#...#.#.#.#...#...#
+ #.#.#####.#.#.#.###.#####.###.#####.#.#####.#.###.#.#.###.#####.#.#.#.#####.#####.#.###.#.#.#.###.#.#.#
+ #.#.#.#...#.#.#.#.#.#.....#.......#.#.#.#.....#...#...#...#.....#.#.#.#.....#.#.#.#.#.....#...#...#.#.#
+ #.###.###.#######.#####.#.#####.#####.#.#.#####.###.#.#.#######.###.#.#####.#.#.#.#.###.#####.###.#.###
+ #.#.#...#.#.#.....#...#.#.......#.......#.....#...#.#.#.......#.....#.#...........#...#...#.#.#.......#
+ #.#.#.###.#.#####.###.#######.#########.#####.#.#############.#####.#####.#########.###.###.#.###.###.#
+ #.#.....#.#.#.#.#...#.#.# U D P I Q L M #.#...#...#.......#.#...#
+ #.#####.#.#.#.#.#.###.#.# E R V Q X T X #.###.###.###.#######.#.#
+ #.#.........#.#.....#.#.# #...#.#.#.#.......#.#.#.#
+ #.###.#######.###.###.#.# #.###.#.#.###.#####.###.#
+ #.#.#...#.....#.#.......# TI......#.........#.#.....#
+ #.#.#.#######.#.###.###.# #.#.#.#.###.#.###.###.#.#
+ #.....#.....#...#.#.#...# #.#.#...#...#.....#...#..IQ
+ #.###.###.#####.#.#.###.# #.#.#.#.#.#####.#.#.#.###
+TI..#...#.....#...#.#...#..WL #.#.#.#.#.#.....#.#.#...#
+ #.#.###.#.#####.#.###.#.# #############.#####.#.###
+ #.#.....#.............#.# #...#...#.#.........#.#.#
+ #######.#.#.#.#.#######.# ###.###.#.#####.#.#####.#
+ #.....#.#.#.#.#.#.#.....# #.............#.#.#.#....UE
+ #.###.###########.###.### ###.#.#######.#####.###.#
+ #...#...#.....#...#...#.# #...#.....#...........#.#
+ ###.###.#.#.#####.###.#.# #.#####.#.###.###.###.#.#
+OG..#...#...#...#.#.#.#.#..OB #.#.....#.#.#...#.#...#.#
+ #.###.#####.###.#.#.###.# ###.###.#.#.#########.#.#
+ #.......#...............# VU....#...#.#.#...#...#...#
+ #.###.#.#.#.#.###.#.##### #.#########.#.#####.#####
+ #...#.#.#.#.#...#.#.#....ZH #...#...#...#.....#.....#
+ #####.#.###.#.#######.### #######.#.#.#.###.#.###.#
+ #...#.#.#.#.#...#.......# #.....#...#.....#.....#.#
+ ###.#####.###.#########.# #.#.###.#####.###.#.###.#
+PV....#.#.....#.#.#.#.#...# #.#.......#.....#.#.#...#
+ #.#.#.#.#.#####.#.#.#.### ###.#.#############.#.#.#
+ #.#.....#.............#.# DS....#.#.#.....#.#.#.#.#..DR
+ #######################.# #######.###.###.#.#######
+ #.................#.....# #.#.#.................#.#
+ #.###.###.#.#.#.#.#.###.# #.#.#.#####.###.#####.#.#
+ #.#...#.#.#.#.#.#.#.#...# SB....#...#.....#.#...#...#
+ #####.#.#########.#.#.### #.###.###.#.###.###.###.#
+ #...#.......#...#...#...# #.......#.#.#...#.#.#...#
+ #.#.#.###.###.#####.###.# #.#.#.#####.#####.#.#.###
+GU..#...#...#...#.#.....#..SS #.#.#.#.#.#.#.#.#.#......QN
+ #############.#.#######.# #####.#.#.###.#.#.#######
+ #.#.#...............#.#.# OJ..#.#.#...#.......#.#....PO
+ #.#.#.#######.#.###.#.### #.#.###.#.#.#####.#.###.#
+AA....#.....#.#.#.#.#.....# #...#...#.....#.#...#...#
+ #.###.#.#.#.#####.#####.# #.#.#.#.#.#####.#.#.#.#.#
+ #...#.#.#.....#.........# #.#...#.#.#...#...#.#.#.#
+ #.#.#.#####.#####.#.##### #.#.###.#.#.###.#.#.#.#.#
+MX..#.....#.#...#.#.#......OQ QN..#.#...#.#.#.#.#.#...#..MH
+ ###.#####.#####.###.##### ###########.#.###########
+ #.#.#.#.#.....#...#.#....MH PO......#.#................YJ
+ #.###.#.#.#######.#####.# #.#.###.#.#.#.###.###.#.#
+ #...#.........#.........# #.#.#.....#.#.#.....#.#.#
+ #.#.#.#.###############.# ###.#.#########.#.#.#.#.#
+OB..#.#.#...#.#.#.#.....#.# #...#.....#.#.#.#.#.#.#.#
+ #.#.#.#.###.#.#.#.#.#.#.# #.#######.#.#.###.#.#####
+ #.#...#...........#.#...# #...............#.#.....#
+ ###.###.#.#.#.#.#####.#.# X D H O G F Y #.#.#.###.###.#####.###.#
+ #.....#.#.#.#.#...#...#.# J C Y G U P J #.#.#.#.....#.....#.#.#.#
+ ###.###.###.#.#.###.#.###########.#.#######.#######.#########.#.#########.#########.###.#######.###.###
+ #.#...#...#.#.#...#.#.#.#.#.....#.#...#.........#...#.........#.....#.......#.....#.#.........#.#.#...#
+ #.#.###.#####.#.#.#####.#.#.###.#.###.#########.#.#####.#########.#####.#######.#####.###.#.#####.###.#
+ #...#.....#.#.#.#...#.#.......#...#.......#.....#.#...........#...#.#.#.............#.#...#...........#
+ ###.###.###.###.#####.#.#.###.#######.#.#####.###.#.#####.###.###.#.#.###.#.###.#.###.#.###.#.#######.#
+ #.#...#...#.........#...#...#.......#.#.#...#...#.#.#...#.#.....#.#.....#.#...#.#.#...#.#...#...#.....#
+ #.#.#.#.###.###.#.#######.#.#.###.#.###.#.#####.#.###.#####.#####.#.#.###.###########.#####.###.###.#.#
+ #...#.#.#.....#.#...#.#...#.#.#.#.#.#.......#...#...#.......#.....#.#...#.......#.#.#.#.......#.#.#.#.#
+ #.#.###.#.#.#.#####.#.#.#.#####.#.#.###.###.###.#.###.#.###.#####.#.#.###.#######.#.#.#####.###.#.###.#
+ #.#...#.#.#.#.#.#.#.#.#.#...#.....#.#.....#.#.#.#...#.#...#...#.....#.#.......#.#.#...#...#.#...#.....#
+ #######.#####.#.#.###.###.#####.#.#####.#####.#.#.#####.#######.#####.###.#####.#.#####.#.#####.#.###.#
+ #.#.#.#.....#.#.#.......#.#.#...#.....#.#.#.....#.....#.#.#.#...#.....#.................#...#...#...#.#
+ #.#.#.#.#.#####.#####.#####.#####.#####.#.###.###.#####.#.#.#######.###.#.#######.###.#.#######.#.###.#
+ #.......#.#.#.#...#.......#.........#.....#.#...#.#.#.....#.#.#.#.#...#.#.....#.#...#.#.......#.#.#...#
+ #.#.###.###.#.###.###.#########.###.###.###.###.#.#.#.###.#.#.#.#.###.#.###.#.#.#######.#########.###.#
+ #.#.#.#...#.......................#.#...#.#.....#...#.#.......#.......#...#.#.#.#...#.#.#.....#...#...#
+ #.###.#.###.###.###.#######.#########.#.#.#.###.###.###.#######.###.#####.#####.#.###.#####.#####.###.#
+ #...#...#.#.#.....#.#...#...#.....#...#.#.....#.#.#.#.#.#.#.#.....#...#.....#...........#.......#.#...#
+ #.###.###.#########.###.###.#.#.###.#.#####.#####.#.#.#.#.#.#######.#.#.#######.###.#####.###########.#
+ #.#.....#.#.#.......#.....#...#...#.#.#.....#.........#.#.#.#...#...#.#...........#...#.#...#.....#...#
+ ###.###.#.#.#######.###.#######.#####.###.#########.#.#.#.#.#.#######.###.#.###.###.###.#.###.#########
+ #...#.......#.......#.#...........#.....#.#.....#...#.#...#...#...#...#...#...#.#.....................#
+ #.###.#.###.#.#.#####.#####.###########.#.#.###.#.###.#.###.#.###.#.###.#.###########.###.###.#########
+ #.#...#.#...#.#.#...................#...#...#...#.#...#.....#.#.....#...#...........#...#...#.........#
+ #################################.###.#########.#####.#######.###.#####.###############################
+ H V Z D S D O
+ Y U H C B S Q
\ No newline at end of file
diff --git a/src/main/resources/day3.txt b/src/main/resources/day3.txt
new file mode 100644
index 00000000..e50c4981
--- /dev/null
+++ b/src/main/resources/day3.txt
@@ -0,0 +1,2 @@
+R991,U77,L916,D26,R424,D739,L558,D439,R636,U616,L364,D653,R546,U909,L66,D472,R341,U906,L37,D360,L369,D451,L649,D521,R2,U491,R409,U801,R23,U323,L209,U171,L849,D891,L854,U224,R476,D519,L937,U345,R722,D785,L312,D949,R124,U20,R677,D236,R820,D320,L549,D631,R42,U621,R760,U958,L925,U84,R914,U656,R598,D610,R397,D753,L109,U988,R435,U828,R219,U583,L317,D520,L940,D850,R594,D801,L422,U292,R883,U204,L76,U860,L753,U483,L183,U179,R441,U163,L859,U437,L485,D239,R454,D940,R689,D704,R110,D12,R370,D413,L192,D979,R990,D651,L308,U177,R787,D717,R245,U689,R11,D509,L680,U228,L347,D179,R508,D40,L502,U689,L643,U45,R884,D653,L23,D918,L825,D312,L691,U292,L285,D183,R997,U427,L89,U252,R475,U217,R16,U749,L578,D931,L273,U509,L741,U97,R407,U275,L605,U136,L558,U318,R478,U505,R446,U295,R562,D646,R988,D254,L68,U645,L953,U916,L442,D713,R978,U540,R447,U594,L804,U215,R95,D995,R818,D237,R212,U664,R455,D684,L338,U308,R463,D985,L988,D281,R758,U510,L232,U509,R289,D90,R65,D46,R886,D741,L327,U755,R236,U870,L764,U60,R391,U91,R367,U587,L651,D434,L47,U954,R707,D336,L242,D387,L410,D19,R203,D703,L228,U292,L19,U916,R411,U421,L726,U543,L240,U755,R157,U836,L397,U71,L125,D934,L723,D145,L317,D229,R863,U941,L926,D55,L2,D452,R895,D670,L216,U504,R66,U696,L581,U75,L235,U88,L609,U415,L850,U21,L109,U416,R408,D367,R823,D199,L718,U136,L860,U780,L308,D312,R230,D671,R477,D672,L94,U307,R301,D143,L300,D792,L593,D399,R840,D225,R680,D484,L646,D917,R132,D213,L779,D143,L176,U673,L772,D93,L10,D624,L244,D993,R346
+L997,U989,L596,U821,L419,U118,R258,D239,R902,D810,R553,D271,R213,D787,R723,D57,L874,D556,R53,U317,L196,D813,R500,U151,R180,D293,L415,U493,L99,U482,R517,U649,R102,U860,R905,D499,R133,D741,R394,U737,L903,U800,R755,D376,L11,U751,R539,U33,R539,U30,L534,D631,L714,U190,L446,U409,R977,D731,R282,U244,R29,D212,L523,D570,L89,D327,R178,U970,R435,U250,R213,D604,R64,D348,R315,D994,L508,D261,R62,D50,L347,U183,R410,D627,L128,U855,L803,D695,L879,U857,L629,D145,L341,D733,L566,D626,L302,U236,L55,U428,R183,U254,R226,D228,R616,U137,L593,U204,R620,U624,R605,D705,L263,D568,R931,D464,R989,U621,L277,U274,L137,U768,L261,D360,L45,D110,R35,U212,L271,D318,L444,D427,R225,D380,L907,D193,L118,U741,L101,D298,R604,D598,L98,U458,L733,U511,L82,D173,L644,U803,R926,D610,R24,D170,L198,U766,R656,D474,L393,D934,L789,U92,L889,U460,L232,U193,L877,D380,L455,D526,R899,D696,R452,U95,L828,D720,R370,U664,L792,D204,R84,D749,R808,U132,L152,D375,R19,U164,L615,D121,R644,D289,R381,U126,L304,U508,L112,D268,L572,D838,L998,U127,R500,D344,R694,U451,L846,D565,R158,U47,L430,U214,R571,D983,R690,D227,L107,U109,L286,D66,L544,U205,L453,U716,L36,U672,L517,U878,L487,U936,L628,U253,R424,D409,R422,U636,R412,U553,R59,D332,R7,U495,L305,D939,L428,D821,R749,D195,R531,D898,R337,D303,L398,D625,R57,D503,L699,D553,L478,U716,R897,D3,R420,U903,R994,U864,L745,U205,R229,U126,L227,D454,R670,U605,L356,U499,R510,U238,L542,D440,R156,D512,L237,D341,L439,U642,R873,D650,R871,D616,R322,U696,R248,D746,R990,U829,R812,U294,L462,U740,R780
\ No newline at end of file
diff --git a/src/main/resources/day4.txt b/src/main/resources/day4.txt
new file mode 100644
index 00000000..4ef936f1
--- /dev/null
+++ b/src/main/resources/day4.txt
@@ -0,0 +1 @@
+372037-905157
\ No newline at end of file
diff --git a/src/main/resources/day5.txt b/src/main/resources/day5.txt
new file mode 100644
index 00000000..e2f7f832
--- /dev/null
+++ b/src/main/resources/day5.txt
@@ -0,0 +1 @@
+3,225,1,225,6,6,1100,1,238,225,104,0,1,192,154,224,101,-161,224,224,4,224,102,8,223,223,101,5,224,224,1,223,224,223,1001,157,48,224,1001,224,-61,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1102,15,28,225,1002,162,75,224,1001,224,-600,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,102,32,57,224,1001,224,-480,224,4,224,102,8,223,223,101,1,224,224,1,224,223,223,1101,6,23,225,1102,15,70,224,1001,224,-1050,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,101,53,196,224,1001,224,-63,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,64,94,225,1102,13,23,225,1101,41,8,225,2,105,187,224,1001,224,-60,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1101,10,23,225,1101,16,67,225,1101,58,10,225,1101,25,34,224,1001,224,-59,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,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,1108,226,226,224,102,2,223,223,1005,224,329,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,344,1001,223,1,223,107,677,226,224,102,2,223,223,1005,224,359,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,374,101,1,223,223,108,226,226,224,102,2,223,223,1006,224,389,101,1,223,223,1007,677,677,224,102,2,223,223,1005,224,404,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,419,101,1,223,223,1107,226,677,224,1002,223,2,223,1005,224,434,1001,223,1,223,1108,226,677,224,102,2,223,223,1005,224,449,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,464,1001,223,1,223,8,226,677,224,1002,223,2,223,1005,224,479,1001,223,1,223,1007,226,226,224,102,2,223,223,1006,224,494,101,1,223,223,1008,226,677,224,102,2,223,223,1006,224,509,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,524,1001,223,1,223,108,677,677,224,1002,223,2,223,1005,224,539,1001,223,1,223,1107,226,226,224,1002,223,2,223,1006,224,554,1001,223,1,223,7,226,226,224,1002,223,2,223,1006,224,569,1001,223,1,223,8,677,226,224,102,2,223,223,1006,224,584,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,1007,226,677,224,1002,223,2,223,1006,224,614,1001,223,1,223,8,677,677,224,1002,223,2,223,1005,224,629,101,1,223,223,107,677,677,224,102,2,223,223,1005,224,644,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,659,101,1,223,223,1008,226,226,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226
\ No newline at end of file
diff --git a/src/main/resources/day6.txt b/src/main/resources/day6.txt
new file mode 100644
index 00000000..28f6c892
--- /dev/null
+++ b/src/main/resources/day6.txt
@@ -0,0 +1,1294 @@
+MB5)V1S
+VYJ)JRF
+SLW)9YR
+CPL)8KQ
+Q5P)H7W
+TJT)139
+PYD)XMX
+4S5)K2V
+RWW)JTL
+HNC)81N
+64N)V96
+RRM)FXW
+Y8R)1C1
+VL8)M6N
+G7L)RQJ
+5C3)SC4
+JZL)DGX
+C7B)KSS
+2X5)5YY
+W91)5R1
+KP8)QYY
+NCL)5WX
+HN9)4LZ
+4Z6)15F
+LHJ)B7D
+S3S)J8Z
+ZCW)KC1
+3TJ)2RP
+J9F)SXH
+SHX)WH9
+M4M)6NK
+23F)Q7S
+B7Y)ZM5
+M7H)D8G
+N8F)K1F
+5PV)SXD
+HGX)5BM
+LH8)C2L
+XFM)ZHM
+H1L)XYG
+4VH)W46
+2Q8)6V5
+G41)LNT
+GNY)Y8R
+95L)MJC
+FPR)X8M
+MS4)YL4
+B8B)YL6
+6N4)SWY
+B65)X7B
+N15)C89
+LX4)TBZ
+3W2)JRH
+MVN)34C
+XMX)DW8
+221)5CM
+QPP)14R
+SRB)7SK
+3P9)MKR
+DGX)6FT
+GQG)T3J
+JS4)XTJ
+9MQ)FKR
+B29)PWB
+XHC)NX1
+55D)YCV
+CV2)3FH
+QN1)MFX
+P2B)B51
+Z4D)Z2S
+3MZ)GYC
+LCQ)FF9
+VPZ)CV2
+Z4D)K9P
+9F2)CV6
+NJS)HRR
+W7Z)6CL
+7NL)M9M
+LJG)426
+6LP)24X
+YQ7)CXX
+4RB)BKC
+KNW)2X5
+KCY)4D2
+2GC)GV9
+YWN)DWL
+JML)131
+JHR)3G4
+KBM)BMX
+GWB)S1P
+LMW)2LL
+DS7)8X3
+8KT)ZCW
+MHT)9XZ
+MV8)B7Y
+VPB)KT8
+6RQ)87P
+RP6)7QR
+KQP)PXT
+GBG)LCQ
+CLY)RVF
+64S)VP8
+FR9)K5X
+K37)QJK
+9ZB)MS1
+V6C)CXT
+SC2)VJS
+B45)9KK
+ZH9)VWY
+R17)XLS
+N5Z)KWV
+QWH)HY7
+2LL)79J
+1DF)RT5
+MGH)XD4
+VZ3)9YW
+413)17F
+YL4)15X
+ZJB)SHX
+HGF)VN7
+4TW)TGX
+3N4)SDF
+KLJ)2FR
+J5R)JZL
+B59)WW6
+KRX)JGM
+N75)78C
+T4B)H2H
+2VB)JG3
+7MG)4N2
+C7M)2BK
+MKR)LBF
+KFX)6KG
+48T)844
+H1W)9XX
+TGX)PN7
+GGK)22B
+M8N)GNY
+L6R)WVW
+VRY)B15
+9YR)6RQ
+QQ6)1KB
+R22)STY
+KC1)6RW
+Q5Z)849
+XWK)VFW
+GFD)C8Z
+L5D)J2Y
+74R)3TJ
+D94)3P9
+JRH)HKV
+3DZ)CFH
+WKN)44S
+JJC)9MQ
+VKT)VBW
+KT8)M7P
+NH8)FDG
+F7N)7MG
+6RQ)RQM
+V4T)ZN8
+25C)2L3
+WJW)DG9
+N5X)SRB
+QZK)GLJ
+WG4)K56
+844)J3V
+HGX)KMR
+87P)HKX
+MK1)WTY
+PC3)4TR
+LG8)B29
+SDR)FWN
+9ZM)SVT
+3K3)XJ6
+WV1)G41
+NKV)36R
+WFG)4M1
+WVW)1TQ
+NQD)WF1
+B9Q)3YV
+CTP)VZB
+72S)NSM
+755)X7S
+MB2)JWB
+GD8)HGX
+3FH)Q1H
+P8P)TD2
+8XK)KP8
+1B4)7LK
+3WC)LXK
+YZP)QZK
+C72)1M6
+VZB)LZV
+TC6)4RB
+DH6)LJG
+6XL)SKB
+G52)3MZ
+THK)F8F
+S1P)NJK
+QPG)5NF
+9J8)W5V
+6CJ)BY3
+F8F)L4S
+L7X)4P2
+9NQ)RWW
+V4V)BSC
+YJW)G7F
+3CK)GMH
+VYR)LRM
+XXP)JML
+Z1S)3QH
+3SH)YBF
+WTY)QR4
+FZ2)BMB
+JZ5)Z5Q
+HDZ)2V9
+CTK)HRP
+VWY)9HX
+YNN)Z5F
+N97)P1K
+8NJ)JBK
+VF7)JD2
+4GG)KC6
+8KS)YJ6
+DH2)HXL
+HB3)1HK
+K56)DFB
+4H6)K6Y
+M7P)3WC
+DG9)88R
+VRB)Y2X
+NMZ)RRS
+T3J)NQ6
+KYZ)KYX
+TNN)48T
+SG7)83G
+JCK)QFN
+5HH)1B4
+16R)C4S
+CQJ)KCS
+6PH)2W6
+89Q)7SB
+NNK)L9J
+77G)KTN
+S2C)YOU
+KFK)57L
+LJ5)1BV
+CCB)XQ8
+14R)T7Y
+3W2)TYQ
+KNC)KF6
+TW1)N5Z
+ZCQ)8NJ
+89G)5XD
+Z15)SMZ
+R5C)VMJ
+CTJ)QWH
+5NF)G52
+24X)SBP
+Z4K)HN9
+6KG)BLM
+66N)152
+CCX)TTM
+P1X)3CM
+Q7Q)KYZ
+VFL)LX4
+SCT)KJ7
+5VK)R8D
+MKH)RZ4
+H2H)WKN
+6V5)9TW
+W4G)QLS
+LZV)D82
+RHL)CLG
+QG8)LX2
+7S1)B7T
+BY3)CMC
+HBP)RD7
+9PR)FVP
+72J)Y14
+PMM)8ZV
+MZ8)MFN
+3GD)8Y5
+ZJ3)WJW
+5HZ)X2V
+FYZ)G5R
+WMR)WT8
+HNZ)6GW
+9XX)33J
+6QS)58X
+11L)VWW
+4LZ)MQT
+MQT)PYS
+BM6)YRP
+658)LG8
+NGZ)1VD
+HRK)ZVG
+RZG)RPJ
+83G)B7B
+JG3)BLQ
+2SG)MQ4
+B6C)4V6
+GLJ)ST5
+7MQ)P9X
+3Y9)1ZB
+K9P)D9Y
+CJ8)LM6
+KCY)VYJ
+GVY)18R
+SZG)QCX
+15F)S5F
+35W)YST
+9NQ)BYJ
+VGX)8LH
+WQM)2HT
+QR4)ZLF
+SWY)HWK
+P9X)HY6
+LGH)ZJ4
+GYC)NGZ
+81F)P4T
+9BF)CTF
+5Q1)1RC
+6MR)3X6
+9HX)X83
+DBQ)C9D
+1KP)9F2
+J8Z)JCK
+Z5R)S2Z
+B7B)KRX
+ZM5)1YF
+H2N)G5C
+FSR)9ZM
+3YV)74R
+93T)MCN
+5HK)MVS
+V22)4Z6
+RSG)N15
+YDJ)F9N
+K6Y)RSZ
+3CM)169
+F2L)39W
+CK4)842
+G6Q)S1W
+D3H)55D
+842)YCL
+NXQ)L67
+KG8)NDS
+LGD)2QJ
+MFX)JLD
+1KB)Z4D
+RMW)CWB
+LC2)QC1
+Q36)HTW
+SG7)CJX
+9BH)N34
+85F)YNF
+LVD)9BH
+7GL)KNC
+SDF)C1Z
+68R)WQC
+BPW)N8F
+3G4)71T
+JFJ)CR2
+YFD)6CJ
+Q8N)XMD
+2CV)X3M
+NPZ)89Q
+SSK)9TP
+QC1)VPZ
+CML)9MV
+4NC)GVY
+T26)9NQ
+8Y5)TDB
+TTM)9PR
+7ZY)3XT
+MQL)PXS
+LXK)2SG
+FWP)LBD
+CSY)C72
+FYQ)B2F
+VYJ)SX8
+ZHV)6QS
+KKB)1ZM
+XRN)6XL
+VN4)6XV
+KWV)KW5
+SBP)971
+BMX)FXV
+7K4)L65
+7XV)791
+DW8)RSK
+9XZ)5CD
+KG8)5C3
+LBD)WZ3
+7DC)T4B
+1J7)XN9
+KF6)GJR
+TPV)FR9
+B7T)89F
+F94)KLB
+3CV)49V
+PN7)J89
+CLY)F2P
+71Z)YZP
+HRR)X9Z
+1SF)QQ6
+MKR)5P3
+XLB)G3P
+3XT)6FC
+WSC)TR9
+1SF)8JZ
+YMK)7T6
+YLW)Q9Y
+LQC)FSX
+971)9LV
+PL3)MMV
+78C)Q72
+NS8)W6M
+RPW)5YW
+91Q)QKC
+B9B)7Q4
+Q3J)B2D
+2ZP)YMK
+MSS)RP6
+N6H)X4V
+5P3)PHS
+7LP)VXP
+FJT)251
+N9G)N71
+21W)XRJ
+FFT)Z22
+89F)VRY
+45S)MZ8
+8J5)98X
+4YF)HCN
+3X6)WFG
+R8D)THY
+YNS)KT3
+2TZ)W6V
+MFN)P6B
+1HK)WSV
+PXS)YQ7
+7LJ)PKH
+QHG)4TW
+G16)7QV
+CXX)GL5
+KDN)NNT
+TPS)JZ3
+X7B)RSG
+6B1)JKD
+CLG)ZGY
+WQC)QTP
+MYZ)3N4
+Y8R)KMW
+YL6)45S
+H25)459
+9TW)M3N
+HDF)SLJ
+LX2)5V6
+6SD)2ZC
+KGQ)XWK
+85H)7ZV
+459)XGH
+VWW)M4M
+27C)CTP
+RKV)FSR
+Z5K)9L1
+2P1)6N1
+WZ3)D94
+TF1)CV3
+1YF)T3S
+F87)N9D
+H7Z)QPP
+NDS)GP1
+GLN)R5Q
+BHV)XRN
+4T5)658
+QRF)HW8
+Q66)WWZ
+2Q6)DWD
+7T6)L9V
+RVF)MXJ
+RZ4)WQM
+V9T)SR2
+M21)CTK
+ZDW)QP4
+WF1)VRB
+VXR)KFX
+NHR)HDF
+11P)TG5
+K2V)YGJ
+NH3)V76
+VNQ)WY7
+G8P)8YY
+W5C)RZG
+W46)T73
+C89)N5X
+2V9)5FQ
+P5K)NCL
+DNK)98T
+FLX)MB5
+VXG)R17
+YQ7)Q36
+L67)K62
+74G)28S
+X9H)L6R
+JRH)CJ6
+LBJ)JHR
+SX8)TF1
+RD7)3P3
+H4X)KPW
+J33)BWF
+R4G)VXR
+XRJ)Y25
+Q7Q)GD8
+2SG)P1X
+4CB)66N
+VYW)FF1
+YB6)CL1
+4QG)TX6
+PKH)FYQ
+JPG)LL9
+M8W)RGV
+XF9)NNK
+COM)Q1M
+SMZ)DS7
+DNP)68R
+1V4)4KY
+GDN)NHR
+8D1)HCL
+KC6)HGF
+CPS)VFL
+33K)XQZ
+Y14)RJ6
+H3F)77G
+NMG)F7N
+FWN)3GD
+36R)MZ3
+MG8)VGX
+6CL)352
+JM4)FRB
+43X)RNH
+TBW)F8R
+JCZ)V22
+11Q)W7Z
+N1L)RVD
+Q6V)DNP
+BWF)Y9G
+H8D)D13
+F8R)4QR
+J1X)8X4
+XFJ)N35
+QTP)869
+G3P)11Q
+K9L)QYX
+KN6)XHC
+MWF)G6Q
+KTN)SYM
+XGH)8MN
+QPP)W52
+G2Y)FBZ
+WBX)ZQ4
+4F7)7XV
+152)KGQ
+CJX)L5D
+JZ3)4ZT
+CCB)N9G
+HK7)K4Q
+JGH)MGH
+VN7)PH4
+M9Z)S9V
+SK8)PYD
+3V9)G45
+ZN8)4QG
+2Q6)HLM
+D13)LYH
+ZQ4)D6G
+SVT)SDR
+PFK)QZ4
+CXT)X31
+44S)5GB
+1RC)PKD
+LWT)G7L
+RX1)VRQ
+P31)WYC
+47S)NMG
+C1Z)YY5
+HWK)GGK
+JC5)1GW
+HVX)395
+W6M)VF7
+JTL)4GD
+G5C)7BN
+PQL)GMS
+NXQ)45D
+S5S)HNZ
+C12)K2D
+7P9)282
+QF5)3W2
+WH4)9VJ
+YNF)M8W
+5V6)DX7
+XQZ)7D2
+XTJ)HM5
+HTR)9H5
+HYN)71Z
+7Q4)TF3
+WH9)GF2
+1CG)Q5Z
+5GB)S3S
+WFF)DJT
+N4C)5BJ
+32D)XB5
+KLB)SC2
+15X)1C3
+GDT)W3X
+1GW)CKZ
+GGJ)4W8
+5BJ)H7Z
+PPT)7S1
+FY4)SCM
+395)3K3
+HFT)K98
+2RP)LZ4
+49V)4LH
+F2T)GCL
+DJR)VTW
+QW3)M8N
+LYH)VYW
+6N1)4YF
+N34)VKT
+1KB)YFD
+3YB)ZB6
+RSZ)F2T
+2FR)1V4
+MDJ)Z4K
+K62)TW1
+J3V)NHJ
+JML)GT8
+6RW)8CP
+8ZV)9BF
+XXP)NMZ
+K4Q)T36
+L4S)22G
+953)XFM
+ZGY)HTR
+RJ6)4H6
+HRP)TQD
+NNT)5YP
+L65)1H8
+KXB)8YB
+T5D)P5K
+LJY)VTL
+SCS)HJ7
+35S)2RZ
+NX1)THK
+HY7)36Z
+FXV)369
+RSK)4Z2
+2Y8)F9B
+NNW)KG7
+WSV)78N
+MMV)5GL
+JLD)WSC
+PZH)N7G
+LL9)4Y4
+1BV)BG2
+XMD)NT6
+H9D)XF9
+MNV)W8J
+SX8)V3N
+P8Y)CW1
+T73)3F9
+D82)32Z
+XPH)PLM
+352)NL6
+Z94)D43
+NK7)7QT
+N35)KHR
+NM1)MG8
+8JZ)TJT
+923)G3N
+MVS)7DH
+YMK)HVQ
+JM4)74G
+HJ7)RPW
+9CY)C7M
+V76)4GG
+LNT)Y2J
+8WD)YNN
+41X)GKF
+TD2)FZ2
+T6H)4TQ
+NHB)NKV
+TV3)RRM
+VRM)LVD
+QNZ)FJT
+3KZ)P8P
+XJ6)3Y9
+4D5)YSS
+WB3)TV3
+1Y6)Q3J
+98T)6WH
+SLT)KQL
+951)5N8
+9ZB)Z6X
+KKD)M4B
+YGJ)4F1
+KBV)PQL
+G45)M7H
+8CP)J9F
+BLQ)2P1
+XS6)NXQ
+BZ9)XQK
+YLN)D1R
+55T)XQB
+N7H)RFF
+FTM)93T
+LJ5)MZ9
+3YB)BFP
+X9Z)7K7
+W8J)9BC
+43X)NM1
+G5R)JGH
+7SK)HRK
+3BL)SWS
+N38)QL4
+HKV)64S
+SDF)W33
+D94)HB3
+GWW)8DQ
+3QH)WFF
+SLJ)2Y4
+3TJ)NQT
+1C3)KLJ
+954)VL8
+LW2)Z6D
+2F1)RQ5
+C1Z)XM7
+3CV)5HH
+QCK)QHS
+XKD)2XP
+24J)221
+8KS)MF3
+5YY)DJQ
+KBH)1W7
+XYG)XHV
+XMW)BTK
+B2D)5T2
+2W6)DH6
+W2R)CK4
+FY4)9RH
+WF1)L7G
+6GW)LBJ
+QCX)H25
+XHV)3DZ
+5Z7)N9H
+RYD)H27
+QVD)ZJ3
+CM1)NHB
+W8J)8KH
+C5D)WV1
+CV3)25C
+953)741
+9MV)ZCQ
+WYC)SLW
+6WH)387
+FXW)1G1
+Z1S)212
+MS1)FYZ
+W33)F78
+NQT)72G
+2XP)1MG
+J9J)KBS
+C1R)RHL
+L7G)R4G
+HWK)CCX
+TNP)1SF
+5R1)SLT
+B51)VDS
+FBK)LH2
+387)XXP
+4NX)RDL
+FF9)XW7
+D3P)5R5
+M3N)YWW
+2Q8)9FM
+8YY)1J7
+Z6X)3CV
+9HX)FV8
+8MN)S2C
+XD4)5HK
+ST7)B59
+LR2)PF2
+23Y)FTM
+7D2)F2H
+9JG)TG9
+2QJ)H4J
+HM5)CSY
+DH5)55T
+GFL)WBX
+HGF)SK8
+PXT)SCT
+K2D)7J8
+78K)MDJ
+2XT)MP2
+4QR)549
+DFB)DRV
+6NK)Q7Q
+5BM)2Y8
+9XZ)DT2
+M25)MV8
+2BK)3V9
+28S)W2R
+RPJ)X37
+QLS)9XF
+X83)XFJ
+8X4)ZHV
+KMR)KDN
+2K2)4T5
+LRM)MWF
+JGM)4D5
+4LH)PZH
+L4X)H2N
+HHH)C12
+R4G)GWB
+ZVP)F22
+YBF)H37
+RSY)PD7
+K3W)VXG
+K9G)HN8
+1C1)QCK
+YTK)JZ5
+KQL)NLZ
+PLM)H7X
+PYS)GDT
+TY2)VRM
+FF9)SZY
+SXH)SZG
+2HT)P19
+JTQ)B5F
+B9B)F2L
+5CM)CPS
+L5D)GQG
+K1F)QNZ
+7QT)LJY
+9KK)1DF
+XN9)KBV
+9VJ)SG7
+M4B)ZDW
+6XV)MQL
+1VL)Z94
+KSS)H8D
+STY)JFJ
+PXR)K3W
+X3M)35W
+RNH)FWP
+2RZ)LW4
+HVQ)QG8
+8VS)QZS
+M8T)4YM
+GJR)SBJ
+N9D)WH3
+4TQ)VZ3
+GG6)6MY
+4TR)M21
+XLS)6QC
+MZ3)YWS
+ZRG)HK7
+V1S)ZRG
+CR2)V8R
+81N)PJX
+VXP)LMZ
+849)LTC
+DWD)LQC
+1H8)3FT
+D2T)KG8
+BYJ)5Q1
+3H6)5X1
+8KQ)CHK
+T7Y)J1X
+4GD)KQP
+XM7)QF5
+9RH)JZR
+GKF)DBQ
+THY)JHZ
+5XD)2GC
+MV8)HBP
+CW1)W91
+411)923
+RRS)8XK
+C66)TNP
+BMX)J5R
+FKR)5Z7
+MRV)PFK
+9BC)59G
+GVY)GDN
+HH8)DRK
+V96)6B1
+SKB)KFK
+DJQ)23Y
+PF2)2HD
+2Y4)D3F
+K86)K1P
+YRP)GBG
+V8R)W4G
+F9N)GP8
+XQB)BPW
+CSY)C66
+NHJ)D2T
+GGF)MK1
+4NX)V6C
+JYC)YNS
+GMS)KNG
+XW7)MRV
+RFS)Q2C
+7NL)WH4
+TBZ)FLX
+RQ5)ZJB
+FPX)WL3
+BMB)K86
+N7G)WC7
+T3S)NQD
+KG7)GLN
+741)CPL
+S1W)G8P
+W5V)ZJJ
+JRF)X8V
+TX6)PK9
+89Q)DFS
+W6V)9FW
+D8G)NVJ
+VBW)3SH
+VTW)RYD
+5CM)QVD
+9TP)LC2
+NCD)4VH
+HLM)11L
+6MY)S68
+S2Z)V3R
+BFP)954
+Z5R)YB6
+SBP)2Q8
+JWQ)TQK
+F2T)VPB
+SZY)PXR
+ML1)ZH9
+LM6)LH8
+CV6)69H
+77Y)G2Y
+22B)JYC
+4Z2)1G9
+5N8)755
+GCL)Q5P
+4ZT)M8T
+Z6H)RKV
+ML1)M9B
+4YM)LFL
+9JG)LMW
+3FT)2XT
+RQM)B6C
+DRV)1Y6
+B1P)3YB
+PGR)YDJ
+9L1)RWV
+79J)41X
+GF8)YTK
+N15)4S7
+8MC)1VL
+4F7)77Y
+SYM)YHV
+4P2)2PZ
+426)2TZ
+H7X)K37
+17F)71V
+9G9)PKR
+KC2)N38
+L4X)WB3
+1TQ)G6B
+YSS)SCS
+Q1M)WW8
+819)2CV
+Q2C)B65
+169)7P9
+139)7DC
+D43)LR2
+KJ7)HH8
+C4S)MHT
+5G8)HDZ
+QTK)J33
+F2H)YBQ
+5YP)YWN
+W52)1SL
+32Z)CM1
+LZ4)2F1
+7SB)QPG
+7K7)SSY
+CW1)9DN
+YCL)LW2
+CTF)N97
+FV8)8KS
+KQP)R1M
+6QC)P2B
+LW4)64N
+R17)FQN
+71V)4CB
+X31)8VS
+5FQ)9ZB
+7J8)D8T
+WZ3)KKB
+VDS)WLZ
+WT8)J9J
+BKC)PC3
+T4B)9G9
+NT6)ST7
+LH2)JCZ
+QHS)RMW
+9LV)PLL
+16M)H1L
+HCN)PMM
+J69)8KT
+35S)7JW
+5C3)F6S
+J89)LJ5
+FVP)LHJ
+RT5)XS6
+LBF)QW3
+8YB)GGF
+ZHM)5HZ
+W3X)MGQ
+KHR)G16
+HY6)DNW
+CMC)VPJ
+Q72)JMG
+WW8)Z6H
+Y25)72S
+3MZ)53C
+791)951
+KPW)S5S
+NQ6)QRF
+NCL)VYR
+1VD)85F
+QYX)413
+NJK)D3H
+N74)MNV
+MP2)F87
+4F1)FQH
+JZR)WMR
+DNW)TNN
+YZP)NH3
+H27)FY4
+28S)6R8
+DRK)B9B
+NTG)1FY
+GL5)HVX
+G3N)CML
+CPS)PQN
+R1M)TY2
+C8Z)MS4
+N71)ML1
+5NF)GF8
+SCM)CCB
+BG2)9JG
+ZVG)6SD
+FBZ)BZ9
+L9V)7ZY
+7DH)B8B
+1JT)DNK
+QL4)NS8
+7LK)35S
+QKC)SAN
+Q1H)DJR
+4N2)C1R
+SC4)R22
+413)WG4
+SXD)K9L
+9CY)4S5
+58X)NCD
+VTL)LGH
+V96)P31
+KYH)CLY
+LTC)MB2
+D9Y)JM4
+53C)F94
+PD7)7MQ
+5GL)6XW
+6FT)H4X
+RQJ)TC6
+WH3)2VB
+M6N)H66
+369)N74
+TF3)JC5
+FGL)NTG
+P6B)1JT
+MDJ)V9T
+6CL)754
+V3N)2Q6
+5YW)KCY
+VRY)24J
+2HD)47S
+WL3)3YH
+1SL)CTJ
+QZ4)697
+S68)KYH
+KBS)FPR
+DT2)H9D
+CHK)Y3R
+Y2X)L7X
+9VJ)3CK
+BLM)CQJ
+PLL)81F
+RFF)5VK
+V3R)LWT
+FQN)M25
+9H5)KHG
+KTN)4NX
+QZS)23F
+H7W)MKH
+PKD)33K
+F2P)MVN
+G6B)GZ6
+8LH)PGR
+NLZ)78K
+GFD)XPH
+LFL)N7H
+D8T)7Z1
+X4V)R2D
+D1R)Q6V
+JV2)DH5
+WLZ)411
+352)C7B
+T36)QWS
+5R5)Q66
+HKX)KC2
+QL9)32D
+M5Q)T6H
+88R)M5Q
+MF3)B1P
+9YW)BM6
+Y9G)VNQ
+M9B)7GL
+57L)YLN
+HTW)PL3
+1ZM)JWQ
+1W7)FFT
+SR2)YJW
+BTK)XKD
+P19)RSY
+BSC)7LJ
+212)NR2
+LX4)K39
+HXL)Z5R
+FSX)W3T
+HN8)FGL
+KFK)27C
+WN2)M9Z
+F9B)GFL
+WY7)Z15
+GQL)21W
+BZ9)KNW
+MFS)9CY
+GV9)NQN
+V8T)91Q
+D7X)GFD
+4KY)Q8N
+9NX)MFS
+YB6)NK7
+Q9Y)1KP
+KCS)B45
+M4B)GG6
+ZVP)2K2
+CWB)N3S
+HVX)JTQ
+59G)TTC
+YMV)B9Q
+16M)XLB
+PJX)VN4
+69H)11P
+LMK)X9H
+F6S)J69
+R2D)5SJ
+X37)17P
+3CL)YMV
+ST5)N4C
+2L3)NH8
+3F9)HNC
+C2L)HFT
+7QP)ZRM
+C12)KN6
+1V9)PPT
+XB5)8J5
+DJT)3BL
+HKV)16M
+YJ6)KBM
+TX6)R5C
+B15)LMK
+549)JPG
+K2V)NJS
+FRB)1CG
+MJC)4NC
+TTC)H1W
+KT3)CJ8
+NR2)85H
+131)3KZ
+X8V)953
+21W)W5C
+3YH)8MC
+VFW)7K4
+D79)KXB
+G7F)JJC
+4M1)7NL
+S9V)NPZ
+VP8)K9G
+KNG)HHH
+D3F)T5D
+SWS)3CL
+TYQ)9NX
+78N)N1L
+RDL)819
+X2V)L4X
+8Y2)GQL
+VRQ)FBK
+1M6)QN1
+MXJ)7LP
+1MG)GTF
+YY5)H3F
+S5F)BHV
+PHS)95L
+6XW)72J
+DFS)D7X
+YWS)SSK
+B1P)DH2
+K98)FPX
+Z5F)6N4
+9DN)78H
+W3T)JS4
+7Z1)5G8
+49V)9J8
+Z6D)GGJ
+V9T)MYZ
+SC4)YLW
+NQN)WN2
+MFN)TBW
+KRX)LGD
+9FW)V8T
+8X3)V4T
+4S7)XMW
+Y2J)5PV
+QYY)T26
+GMH)JV2
+H98)Q2Y
+MZ9)2ZP
+ZRM)KBH
+251)Z5K
+KHG)HYN
+5WX)P8Y
+71T)N75
+H37)6PH
+HCL)D3P
+M25)16R
+K39)QL9
+WWZ)8Y2
+PK9)N6H
+LMZ)ZVP
+Z5Q)H98
+JKD)WK2
+JHZ)43X
+PQN)NNW
+J2Y)3H6
+YWW)GWW
+NL6)KKD
+XQ8)TPS
+RWV)8D1
+TDB)RX1
+2PZ)6MR
+NSM)QTK
+GP1)TPV
+ZB6)1V9
+QHG)4F7
+18R)D79
+ZJJ)Z1S
+45D)7QP
+7QV)X42
+M9M)MSS
+TQK)V4V
+Q7S)23K
+TG9)C5D
+VMJ)89G
+7QR)SPB
+RGV)QHG
+3P3)RFS
+GT8)6LP
+P1K)8WD
\ No newline at end of file
diff --git a/src/main/resources/day7.txt b/src/main/resources/day7.txt
new file mode 100644
index 00000000..1ecb0de6
--- /dev/null
+++ b/src/main/resources/day7.txt
@@ -0,0 +1 @@
+3,8,1001,8,10,8,105,1,0,0,21,30,47,60,81,102,183,264,345,426,99999,3,9,1002,9,5,9,4,9,99,3,9,1002,9,5,9,1001,9,4,9,1002,9,4,9,4,9,99,3,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,1001,9,3,9,1002,9,2,9,101,5,9,9,1002,9,2,9,4,9,99,3,9,102,4,9,9,101,4,9,9,1002,9,3,9,101,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,99
\ No newline at end of file
diff --git a/src/main/resources/day8.txt b/src/main/resources/day8.txt
new file mode 100644
index 00000000..1838f93f
--- /dev/null
+++ b/src/main/resources/day8.txt
@@ -0,0 +1 @@
+222122222222222221222222020220220222201212222222121120222212202222222222222222202222222222222222210222202222222201222222122022222022022222222222222212222122222222222221222222022222220222211202222222020221222222222222222222222222222222222222222222210222222222222211222222122022222022022222222222222222222022222222222222222222021222221222222202222122121122222202222222222222222222202222222222222222220222212222222202222222222222222222222222222222222212212022222222222221222222222221220222200202222222120220222212222222222222222222212222222222222222200222202222222210222222022022222122122222222222222222222022222222222221222222022221222222220212222122021022222212222222222222222222212222222222222222202222202222222200222222022122222222022222222222222212212022222222222221222222022222221222212222222222220020222222102222222222222222202222222222222222220222212222222212222222122122222122022222222222222222212222222222222222222222120220222222220222222222221122222222022222222222222222222222222222222222212222222222222221222212222122222122222222222222222212212022222222222220222222121220222222202202222022220221222212202222222222222222212222222222222222202222222222222220220202222022222022122222222222222212222122122222222221222222121221222222201202222022121120222212222222222222222222222222220222222222221222212222222210222212022122222022222222222222222212222022122222222220222222022222220222202222222022122022222212112122222222222222202222221222222222220222222222222201221222022022222022222222222222222212211022222222222220222222022220221222222212222222122010222212102122222222222222212222220222222222211222222222222222222222222022222122222222222222222202210122022222222221222222120222222222211212222022121200222222022222222222222222222222220222212222202222212222222221221212122222222022022222222222222212202122122222222220222222020222220222202222222122222121222202112122222222222222222222220222202222222222202222222211221222222102222022122222222222222222202222022222222221222222222220222222202202222222021120222222112122222222222222212222221222202222202222212222222212222202122012222022122222222222222202222122022222212222222222221220220222221212222222020011222222122122222222222222222222220222212222211222202222222211222212021202222222122222222222222202202222022222212221222222021222221222220202222022120012222212012122222222222222202222221222202222222222202222222221222212120002222022222222222222222202222222022222202222222222020221221222212222222122022000222222102122222222222222222222222222202222210222222222222201220222021122222222122222222222222222210222022222212222222222122220222222220012222222122201222202002022222222222222202222222222222222201222202222222211220202120122222222222222222222222212202122022222212220222222220222221222212112222222022021222202202022202222222222012222222222222222210222212222222222222012020022222022122222222222222202222121222222222221222222022220220222210112222122221122222202222222202222222222212222221222222222210222212222222212220202120222222222222222222222222222210120022222202222222222022220222222220002222202022211222222012122202222222222002222221222202222221222212222222221221212122122222022022222222222222222221222222222212220022222121220222222221102222112121101222202202222212222222222112222020212222122220222202222222200220022022112222222022222222222222222222120122222202220222222021221220222202222222022122121222212122222212222212222102222220202202222211222222222222211222022020112222222222222222222222212201121022222202220022222222220220222210122222122122020222222112122212222202222202222220222222022200222202222222210220102121022222022222222222222222222212021222222202222222222022221222222222122222212220201222212202222212222222202012222221222222122200222202222222211222122122212222022022222202222222202202121222222202222021222120220221222201002222212120221222202122222212222212202112222221222222002212222212222222220222022220212222222022222222222222222211122122222202222222222121222220222221212222202221020222212112122202222222212112222122222202002211222212222222220221102121012222222122222202222222202222122122222212222222222122222220222211012222122022022222212102022202022202222202222122222222112210222222222222202222102122212222222022222212222222222212222022222220221021222120221220222221000222112121000222222202222222022222212102222222202222122212222222222222201220212221122222222122222222222222212201022022222220221122222221221220222221211222022222020222212222122212222222112202222120222202112211222202222222221222112020112222022022222202222222222211122022222221220220222221220220222222121222102222210222212002022212222222222212222121212212022222222202222222202221012020212222022222222212222222222212221022222212221220222221220221222222000222122020011222222202222222122212202002222221222222022102222212222222202220202021002222122122222212222222222220221122222202221220222221222222222222212222122121010222222102222212022222122022222120202202012110222222222222220221022122222222222122222202222222212200222222222202222020222221221222222202200222022121200222202112022212022212222222222021220202002111222222222222221220122121202222222222222202202222202212121122222222222120222221220200222220210222102121221222212212221222022212212222222221221202012112222222222222220220002021012222222022221222202222212202120122222200222221222221222221222210011222212021222222222212222202222222022022222021220202122022222202222222220220112221222222122122221222212222222222121022222200221221220020220201222222002222212122200222212122122202122022212112222221221202202212222212222222211222222220222222022122222002222222222201120222222220222220220120221200222211212222112221210222212212220212022012122022222220221212102001222202222222222220112020002222022222220102222222202212020022222201221020222122220222222211111022012220122222222012122202222202222222222122222212222002220202222222221221212021102222122022220002212222202210020122222202221120221121220202222221001022202220111222212112021212222222102112222022202202022020221222222222200220102220222222022022220122202222212222021022222210222120221021222210222222120222212120020222222212022202022112102122222020222212022222222202222222220220202222102202222022222002212222212211222122222200221220222220221221222222001022022021112222202102021212122122122222222220222212202201220202222222212220212021212212222020020022212222212201220222220212222221120010220202222201220222202122002222212112222202122112112212222121220222212002221002222222201222002221002222222220121022212222202211121222222212222221222001222202222210010222112021202222212102120202222222122002222120221222122020222122222222211222222222222210122221122022202222222212021122221202220120222000222221222212002022112022012222202222022222022212012002222122220212022122220112222222200220002022212202122220120022212222202221220222221201220021122121222220222211212122212222220222202022122222022102002222222121210222202022221112222222220221022020012210222221221222212222212220120022222211222221120022220212222210012222012122012222222202222222222202112222222021200212202200221202222222201222012222002211222221022112222222202202220222221220222021020021221211222221111222102020000222222202220202122002102022222221211122102120211002222222212222002120022222212222220022202222212202221222222210221120020201221212222221100222002022121222022202221222222002022002222121212212111211212122222222222222202122002200112220120202222222212211221222222021221222120210221222222220022222022022012222122112020212022022122012222221210102202021200202222222200221202121202210122222122012202222202201122222221120220022222112222221222201211122002121020222012222021202222020212112222122200122121102211002222222200220212220202220012221122012212222202202220122210000222220022010221211222212022022112022212222102002122222222111212202222220222022211202211112202222010221122222202222102122020102212222222221121222201021221221022210221221222201022022012021220222112022121202022222012202222120200002002110200222200222000221022101022222002021021222202222222200220222200101220122122020222201222210112022102021112222002202022202222022212122222122222222020220221102220222020222222212012201012020222222012220222101222122202100222120021120222202222221122022202122212222012002220212022120122002222220200122002201220002200222020220012011022220122120022012012221212121222122221000221021020221221220222211201122012020121222212122121212022000002122222220221102222012221122210222211212212122022210002221121122012221222022122122220012222120021002222201222200222022102022222222022022120212122121122022222020220202011001221222210222200201002122222200122122120102202220202212020222200010221021021120220222222222121222002122201222022002220202022210012002222022210212220020200022211222121221102120212212002221122022202210222110121122210101220020222002220200222212111122112221120222002122221202022120222002222122220212120101201202201222222221102200212212212121121022212210202002221022221022220120020100222201222201121122002121021222022012020222022201022122222122202102001022200022220222121222012021122212212221221222222212222010220122201012221022012002220212222222111222212122112222012202222212122010122022222121210022112010202202201222122210202112012200012120020201122220212020122022221012220222111020220221222201222022002121022222202102220222122212002202222020202112121222200122221222101211202022111210122122220020202210212021122222222012222120221201222220222211222122012220121222202012020212122202122202222120210212210202220122210222020220222101212200002220120220112211202000122022201100222022201111221202222202022122112122001222002202022222122221102102222021211102220220221002200222112221022220200200022222022212122212212111222022221121221021201202220221222202211122122122222222022212021212022021012202222021211012110221201212220222121211212022012220022021121011012202222211020122210122221122110120222200222212100022102021111022222112122212222021102022222022221222121101222212210202210221012220112201222122022121112202012210221222202221221020022100221210222220121222102020201122102212020222122121212122222120201122110121222212222202112222212220111221002120220101212220122012022120200021222120021010221212222220100122112121221222102202120212122012122102220222202202000120211222222202102220122002122222202020221011212222212010220220222122221022211010220220222220010122002020021122002112122212022112122012221122201002222022212012222212110212022201000211112222021121012222222210121020202200220121210100220221222220001122022020222222212212222212122021002102221222211122000202212112210222001201102001102210112120221102112201012102221121201202221021110012222210222222012022112221200022022022122202212000002012222121212012220010200022201212101211202222122201102122020211102220212010221020222102221020022200220201222210211022202022210122022002221222012010212122211221221102201022211102220212110222022110121200222122122002212210122211220220221222221222201220221120222210011222022121111222102022222222012000022002200220222102012110221012212202201211122220021200012121122202122211022221121021212100220120012002222120222202210022022220020122012222222202212100022222211020210102220202211222211202220221122001011211222122122211212221112202122120200011220120212201221110222220202022012021012222012002220212022220222002221120220202110000211012202212020221122211110221222220220100112212222221021222220011222021001120220211222200121022222120101022202202020222002212222102222022212122011220202022220202020211022022220212222220222111112201212010120221210212221122120212221101222202212122212222120222102122122222202101022112202220212202220000200122210222012211122022100200022220222001002220202122121220201021221000002101221122222200112122102122012022112212121222112210212012210022221212002102220212211222100200012001202201012122020020012211022200121122222102220000002210221211222221122222022020201122022102222222102200002022212222000012211121201122211212121222012100121212122222020122102211002022021222210012222221001020220111222222011222022022210122112202022202222201012022212120221202202222221012211202021210022221011221022122020201212201012220122022222112221102011211222102222210010222012122110122222212121212222221012122202222201222202120220022210222110221212002122220222220120221102201202111021222200122222212010012220210222212021022112022011022012202221202112021002122210121002202100101200122210212021202112122000220222221020202012201002201021221201111222101021011222222222210020022002020200122002112122222222202102002210220102122211121201102212212012212202222201222022020122020212211212210221021221011222100002221221012222210100022202121010022222112021202102011102012201220211022022000201122220222020222012022021202102020122010012222102001022022202011220012112201221201222220101022102021210022212122020212122000102102222220202222100200222122201202110220012001122222012020220102112220212100121121202102220221201122221010222210002022202221000122212012222202102201212022210010111002211211211202212202200202222200001212112121222002122221012002121022210222221222120020222212222212121022112222011022222202220222102020012122220020012022111112211102222212202220012020212201022222122002002222002222222122012102221021121121221221222210122222212220110022212222222222202220022212220122120112002121220212212222101200202112000220112001120020112220222211122020120210222120202210220222222210120022122120021022222012220202102200112212220002211002201102212212212222121220212122221212002021122101222202222022021220122222222210101000222202222201100022122222101222102222200202022212022012221201202112211212210022202222011220202221010200112001221222122212012122120120022021221222111222221211222221121222202122121122122012002222002222210112210102002202202011210202210222011222122212222200012211020200202220002111002121001020222022222121222020222222000022222021200122012112210212012001000122200000201022102010200112111222220211112120010201102020222221122212012121121022022120222200101102022210222200111022012120111022012022100222212012022002201221111102200102220212101202220221122111010201112212121020112201222201112020120201221001121120220220222212012222222120021022202102112012102012212222212022120202220000202120211222222222122202022211112201020100202222102020120222101120221101110100221221222210000122120121110222112122002122222101121222201000222122201122202202220222020202012222000220212100020021122201122022212222110022221211101210021021222220200022201022001112022122112222002202121122200111210122021221210210102212211221212222120212202200021212122211202202200121101001221021021221021022222202122022210122012212122212012202102022221222111020111112120221210210020222110200202112111202002020121210012210012102002020000221222200002210020220202221110122121020222102002102100022222121101222102120001112101222202001022222101221102021112200102200222022002220102210111121221220221202020011222102222210020222021022211002202002120112202120111222121002002022112112200200221212000201122110100200212020122012202201122122000212211222011122220200201100111000022010102201221120010110121011120100100011202001101011012210020022201001212022210200111020120211112200111000100
\ No newline at end of file
diff --git a/src/main/resources/day9.txt b/src/main/resources/day9.txt
new file mode 100644
index 00000000..e3d2a86a
--- /dev/null
+++ b/src/main/resources/day9.txt
@@ -0,0 +1 @@
+1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,550,1027,1101,0,0,1020,1101,30,0,1004,1101,0,22,1014,1102,1,36,1009,1101,37,0,1007,1102,25,1,1010,1102,1,33,1012,1102,282,1,1029,1102,1,488,1025,1101,0,31,1019,1101,0,21,1008,1101,0,35,1015,1101,664,0,1023,1102,26,1,1001,1101,28,0,1016,1102,29,1,1005,1102,1,24,1002,1101,20,0,1018,1101,27,0,1013,1101,38,0,1017,1102,1,1,1021,1102,1,557,1026,1102,1,39,1000,1101,23,0,1006,1101,493,0,1024,1102,1,291,1028,1101,671,0,1022,1101,0,34,1003,1101,0,32,1011,109,10,21108,40,40,8,1005,1018,199,4,187,1105,1,203,1001,64,1,64,1002,64,2,64,109,-14,2108,30,8,63,1005,63,225,4,209,1001,64,1,64,1105,1,225,1002,64,2,64,109,3,2102,1,4,63,1008,63,34,63,1005,63,251,4,231,1001,64,1,64,1106,0,251,1002,64,2,64,109,12,2107,22,-5,63,1005,63,269,4,257,1105,1,273,1001,64,1,64,1002,64,2,64,109,20,2106,0,-3,4,279,1001,64,1,64,1106,0,291,1002,64,2,64,109,-16,21108,41,40,-3,1005,1012,311,1001,64,1,64,1105,1,313,4,297,1002,64,2,64,109,-13,2101,0,2,63,1008,63,30,63,1005,63,335,4,319,1105,1,339,1001,64,1,64,1002,64,2,64,109,-3,2102,1,4,63,1008,63,35,63,1005,63,359,1106,0,365,4,345,1001,64,1,64,1002,64,2,64,109,15,1205,6,377,1105,1,383,4,371,1001,64,1,64,1002,64,2,64,109,5,21102,42,1,-2,1008,1017,39,63,1005,63,403,1106,0,409,4,389,1001,64,1,64,1002,64,2,64,109,-17,21107,43,44,10,1005,1012,431,4,415,1001,64,1,64,1106,0,431,1002,64,2,64,109,14,21107,44,43,-4,1005,1012,451,1001,64,1,64,1106,0,453,4,437,1002,64,2,64,109,1,21102,45,1,-3,1008,1014,45,63,1005,63,479,4,459,1001,64,1,64,1105,1,479,1002,64,2,64,109,7,2105,1,0,4,485,1106,0,497,1001,64,1,64,1002,64,2,64,109,5,1206,-8,513,1001,64,1,64,1106,0,515,4,503,1002,64,2,64,109,-33,2101,0,7,63,1008,63,32,63,1005,63,535,1106,0,541,4,521,1001,64,1,64,1002,64,2,64,109,23,2106,0,8,1001,64,1,64,1106,0,559,4,547,1002,64,2,64,109,-1,21101,46,0,-5,1008,1013,46,63,1005,63,585,4,565,1001,64,1,64,1105,1,585,1002,64,2,64,109,-4,21101,47,0,2,1008,1016,44,63,1005,63,605,1105,1,611,4,591,1001,64,1,64,1002,64,2,64,109,-18,1207,4,38,63,1005,63,627,1106,0,633,4,617,1001,64,1,64,1002,64,2,64,109,5,2107,22,7,63,1005,63,649,1106,0,655,4,639,1001,64,1,64,1002,64,2,64,109,12,2105,1,10,1001,64,1,64,1106,0,673,4,661,1002,64,2,64,109,-10,1208,6,33,63,1005,63,693,1001,64,1,64,1106,0,695,4,679,1002,64,2,64,109,-7,2108,35,7,63,1005,63,715,1001,64,1,64,1106,0,717,4,701,1002,64,2,64,109,6,1208,5,37,63,1005,63,735,4,723,1106,0,739,1001,64,1,64,1002,64,2,64,109,-4,1202,5,1,63,1008,63,34,63,1005,63,765,4,745,1001,64,1,64,1105,1,765,1002,64,2,64,109,29,1206,-7,783,4,771,1001,64,1,64,1105,1,783,1002,64,2,64,109,-28,1201,6,0,63,1008,63,29,63,1005,63,809,4,789,1001,64,1,64,1106,0,809,1002,64,2,64,109,5,1202,2,1,63,1008,63,20,63,1005,63,829,1106,0,835,4,815,1001,64,1,64,1002,64,2,64,109,-1,1201,6,0,63,1008,63,35,63,1005,63,859,1001,64,1,64,1105,1,861,4,841,1002,64,2,64,109,2,1207,-3,25,63,1005,63,879,4,867,1105,1,883,1001,64,1,64,1002,64,2,64,109,13,1205,3,901,4,889,1001,64,1,64,1106,0,901,4,64,99,21101,0,27,1,21101,915,0,0,1106,0,922,21201,1,22987,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1106,0,922,22101,0,1,-1,21201,-2,-3,1,21101,0,957,0,1106,0,922,22201,1,-1,-2,1105,1,968,21202,-2,1,-2,109,-3,2105,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
\ No newline at end of file
diff --git a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
new file mode 100644
index 00000000..760ce827
--- /dev/null
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -0,0 +1,45 @@
+package com.sbaars.adventofcode2019;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.days.Day11;
+import com.sbaars.adventofcode2019.days.Day13;
+import com.sbaars.adventofcode2019.days.Day2;
+import com.sbaars.adventofcode2019.days.Day5;
+import com.sbaars.adventofcode2019.days.Day7;
+import com.sbaars.adventofcode2019.days.Day9;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class IntcodeTest extends TestCase {
+ public void testDay2() throws IOException {
+ Assert.assertEquals(8017076L, new Day2().part1());
+ Assert.assertEquals(3146, new Day2().part2());
+ }
+
+ public void testDay5() throws IOException {
+ Assert.assertEquals(11049715L, new Day5().part1());
+ Assert.assertEquals(2140710L, new Day5().part2());
+ }
+
+ public void testDay7() throws IOException {
+ Assert.assertEquals(116680L, new Day7().part1());
+ Assert.assertEquals(89603079L, new Day7().part2());
+ }
+
+ public void testDay9() throws IOException {
+ Assert.assertEquals(2518058886L, new Day9().part1());
+ Assert.assertEquals(44292L, new Day9().part2());
+ }
+
+ public void testDay11() throws IOException {
+ Assert.assertEquals(2172, new Day11().part1());
+ Assert.assertEquals("JELEFGHP", new Day11().part2().toString());
+ }
+
+ public void testDay13() throws IOException {
+ Assert.assertEquals(320, new Day13().part1());
+ Assert.assertEquals(15156, new Day13().part2());
+ }
+}