From 4745bf122e3b6500b4de676f32f6409107bf76ce Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 3 Dec 2019 14:17:42 +0100
Subject: [PATCH 001/120] Day 1

---
 .../sbaars/adventofcode2019/days/Day1.java    |  38 +++++++
 src/main/resources/day1.txt                   | 100 ++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day1.java
 create mode 100644 src/main/resources/day1.txt

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..2ebdff09
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
@@ -0,0 +1,38 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day1 implements Day, DoesFileOperations
+{	
+    public static void main(String[] args) throws IOException
+    {
+    	new Day1().printParts();
+    }
+
+	public int part1() throws IOException {
+		return createNumberStream().map(this::getFuel).sum();
+	}
+	
+	public int part2() throws IOException {
+		return createNumberStream().map(this::getRequiredFuel).sum();
+	}
+
+	private IntStream createNumberStream() throws IOException {
+		return Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day1.txt").getFile())).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/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

From 2cd8115b285aab50e1afa264294178d750346d1b Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 3 Dec 2019 14:17:51 +0100
Subject: [PATCH 002/120] Day 2

---
 .../sbaars/adventofcode2019/days/Day2.java    | 59 +++++++++++++++++++
 src/main/resources/day2.txt                   |  1 +
 2 files changed, 60 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day2.java
 create mode 100644 src/main/resources/day2.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
new file mode 100644
index 00000000..2c8c72a9
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -0,0 +1,59 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day2 implements Day, DoesFileOperations {
+
+	public static void main(String[] args) throws IOException {
+		new Day2().printParts();
+	}
+	
+	public int part1() throws IOException {
+		return execute(12, 2);
+	}
+
+	private int execute(int x, int y) throws IOException {
+		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day2.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
+		program[1] = x;
+		program[2] = y;
+		for(int i = 0; executeInstruction(program, i, program[i]); i+=4);
+		return program[0];
+	}
+
+	private boolean executeInstruction(int[] program, int i, int instruction) {
+		switch(instruction) {
+			case 1:
+				program[program[i+3]] = program[program[i+1]] + program[program[i+2]];
+				break;
+			case 2: 
+				program[program[i+3]] = program[program[i+1]] * program[program[i+2]];
+				break;
+			case 99: 
+				return false;
+			default: throw new IllegalStateException("Something went wrong!");
+		}
+		
+		return true;
+	}
+
+	@Override
+	public int part2() throws IOException {
+		for(int i = 0;;i++) {
+			for(int j = 0; j<=i; j++) {
+				for(int k = 0; k<=i; k++) {
+					try {
+						if(execute(j, k) == 19690720) {
+							return 100 * j + k;
+						}
+					} catch(Exception e) {}
+				}
+			}
+		}
+	}
+
+}
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

From 5bb102d8e4915d5bada28d0e50e7263f2cddf088 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 3 Dec 2019 14:17:58 +0100
Subject: [PATCH 003/120] Day 3

---
 .../sbaars/adventofcode2019/days/Day3.java    | 144 ++++++++++++++++++
 src/main/resources/day3.txt                   |   2 +
 2 files changed, 146 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day3.java
 create mode 100644 src/main/resources/day3.txt

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..40e9ae94
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -0,0 +1,144 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.File;
+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.util.DoesFileOperations;
+
+public class Day3 implements Day, DoesFileOperations
+{	
+	private Set<Step> intersect;
+	
+	private Day3() throws IOException {
+		String[] strings = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day3.txt").getFile())).split(System.lineSeparator())).toArray(String[]::new);
+		Walk[] walks1 = mapToWalks(strings[0]), walks2 = mapToWalks(strings[1]);
+		Set<Step> walkedLocations = new HashSet<>();
+		calculateDistance(walks1, walkedLocations, false);
+		this.intersect = calculateDistance(walks2, walkedLocations, true);
+	}
+	
+    public static void main(String[] args) throws IOException
+    {
+    	new Day3().printParts();
+    }
+
+	public int part1() throws IOException {
+		return intersect.stream().mapToInt(e -> distance(e.point)).min().orElse(Integer.MAX_VALUE);
+	}
+
+	private Set<Step> calculateDistance(Walk[] walks1, Set<Step> walkedLocations, boolean collect) {
+		Set<Step> intersectingLocations = new HashSet<>();
+		int x = 0, y = 0, steps = 0;
+		for(Walk walk : walks1) {
+			for(;walk.distance>0;walk.distance--) {
+				switch(walk.dir) {
+					case UP: y++; break;
+					case DOWN: y--; break;
+					case LEFT: x--; break;
+					case RIGHT: x++; break;
+				}
+				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);
+				}
+				steps++;
+			}
+		}
+		return intersectingLocations;
+	}
+	
+	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);
+	}
+
+	public int part2() throws IOException {
+		return intersect.stream().mapToInt(e -> e.steps).min().orElse(Integer.MAX_VALUE);
+	}
+	
+	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));
+		}
+	}
+	
+	class Step {
+		private final Point point;
+		private int steps;
+		private boolean isCombined = false;
+		
+		public Step(Point point, int steps) {
+			this.point = point;
+			this.steps = steps + 1;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + getEnclosingInstance().hashCode();
+			result = prime * result + ((point == null) ? 0 : point.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Step other = (Step) obj;
+			if (!getEnclosingInstance().equals(other.getEnclosingInstance()))
+				return false;
+			if (point == null) {
+				if (other.point != null)
+					return false;
+			} else if (!point.equals(other.point))
+				return false;
+			return true;
+		}
+
+		private Day3 getEnclosingInstance() {
+			return Day3.this;
+		}
+		
+		public void combine(Step step) {
+			if(!isCombined) {
+				steps+=step.steps;
+				isCombined = true;
+			}
+		}
+	}
+	
+	enum Direction {
+		UP, DOWN, LEFT, RIGHT;
+		
+		public char directionCode() {
+			return name().charAt(0);
+		}
+		
+		public static Direction getByDirCode(char code) {
+			return Arrays.stream(values()).filter(e -> e.directionCode() == code).findAny().get();
+		}
+	}
+}
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

From 8cfc7fb88c5305470d2fc54db263307282138f60 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 4 Dec 2019 09:22:33 +0100
Subject: [PATCH 004/120] Day 4

---
 .classpath                                    |  5 ++
 .settings/org.eclipse.core.resources.prefs    |  1 +
 .../sbaars/adventofcode2019/days/Day4.java    | 58 +++++++++++++++++++
 3 files changed, 64 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day4.java

diff --git a/.classpath b/.classpath
index 5e8a55fe..cd377e47 100644
--- a/.classpath
+++ b/.classpath
@@ -23,5 +23,10 @@
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>
 	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="target/classes"/>
 </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/<project>=UTF-8
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..5ec9ea2b
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
@@ -0,0 +1,58 @@
+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 int part1() throws IOException {
+		return checkPasswords(false);
+	}
+	
+	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;
+	}
+
+
+	@Override
+	public int part2() throws IOException {
+		return checkPasswords(true);
+	}
+
+	private int checkPasswords(boolean checkGroup) {
+		return Math.toIntExact(meetsCriteria(372037, 905157, checkGroup));
+	}
+
+}

From a3f1490b10e3877bba1d96115c263cd0b6482c90 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 4 Dec 2019 12:15:46 +0100
Subject: [PATCH 005/120] Simplified Day 2 after re-reading requirements

---
 .../com/sbaars/adventofcode2019/days/Day2.java    | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index 2c8c72a9..b3b3df3c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -43,17 +43,14 @@ private boolean executeInstruction(int[] program, int i, int instruction) {
 
 	@Override
 	public int part2() throws IOException {
-		for(int i = 0;;i++) {
-			for(int j = 0; j<=i; j++) {
-				for(int k = 0; k<=i; k++) {
-					try {
-						if(execute(j, k) == 19690720) {
-							return 100 * j + k;
-						}
-					} catch(Exception e) {}
+		for(int i = 0; i<99;i++) {
+			for(int j = 0; j<99; j++) {
+					if(execute(i, j) == 19690720) {
+						return 100 * i + j;
+					}
 				}
-			}
 		}
+		return -1;
 	}
 
 }

From 915542d4a6f52255bd665e19d6ce8c662915d61a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 4 Dec 2019 12:31:00 +0100
Subject: [PATCH 006/120] Day 2: More concise code

---
 .../java/com/sbaars/adventofcode2019/days/Day2.java   | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index b3b3df3c..ea78188d 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -27,14 +27,9 @@ private int execute(int x, int y) throws IOException {
 
 	private boolean executeInstruction(int[] program, int i, int instruction) {
 		switch(instruction) {
-			case 1:
-				program[program[i+3]] = program[program[i+1]] + program[program[i+2]];
-				break;
-			case 2: 
-				program[program[i+3]] = program[program[i+1]] * program[program[i+2]];
-				break;
-			case 99: 
-				return false;
+			case 1: program[program[i+3]] = program[program[i+1]] + program[program[i+2]]; break;
+			case 2: program[program[i+3]] = program[program[i+1]] * program[program[i+2]]; break;
+			case 99: return false;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
 		

From a677b8d872129b5ce8467aacd8ad3f82af48974f Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 4 Dec 2019 12:36:23 +0100
Subject: [PATCH 007/120] Day 3: Refactoring

---
 .../sbaars/adventofcode2019/days/Day3.java    | 50 +++++++------------
 1 file changed, 17 insertions(+), 33 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 40e9ae94..794bdc38 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -42,21 +42,25 @@ private Set<Step> calculateDistance(Walk[] walks1, Set<Step> walkedLocations, bo
 					case LEFT: x--; break;
 					case RIGHT: x++; break;
 				}
-				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);
-				}
+				performStep(walkedLocations, collect, intersectingLocations, x, y, steps);
 				steps++;
 			}
 		}
 		return intersectingLocations;
 	}
+
+	private void performStep(Set<Step> walkedLocations, boolean collect, Set<Step> 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);
@@ -92,34 +96,14 @@ public Step(Point point, int steps) {
 
 		@Override
 		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result + getEnclosingInstance().hashCode();
-			result = prime * result + ((point == null) ? 0 : point.hashCode());
-			return result;
+			return 31 + ((point == null) ? 0 : point.hashCode());
 		}
 
 		@Override
 		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
+			if (!(obj instanceof Step))
 				return false;
-			if (getClass() != obj.getClass())
-				return false;
-			Step other = (Step) obj;
-			if (!getEnclosingInstance().equals(other.getEnclosingInstance()))
-				return false;
-			if (point == null) {
-				if (other.point != null)
-					return false;
-			} else if (!point.equals(other.point))
-				return false;
-			return true;
-		}
-
-		private Day3 getEnclosingInstance() {
-			return Day3.this;
+			return point.equals(((Step) obj).point);
 		}
 		
 		public void combine(Step step) {

From 07a21a4ce294937559e6b11495eb0db9d0050c46 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 5 Dec 2019 15:23:22 +0100
Subject: [PATCH 008/120] Day 5 Part 1

---
 .../sbaars/adventofcode2019/days/Day2.java    |   2 +-
 .../sbaars/adventofcode2019/days/Day5.java    | 128 ++++++++++++++++++
 src/main/resources/day5.txt                   |   1 +
 3 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day5.java
 create mode 100644 src/main/resources/day5.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index ea78188d..4ecdb381 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -18,7 +18,7 @@ public int part1() throws IOException {
 	}
 
 	private int execute(int x, int y) throws IOException {
-		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day2.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
+		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day2.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
 		program[1] = x;
 		program[2] = y;
 		for(int i = 0; executeInstruction(program, i, program[i]); i+=4);
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..1b0920b3
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -0,0 +1,128 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day5 implements Day, DoesFileOperations {
+	
+	boolean parameterMode = true;
+	private static int NUM_MODES = 3;
+	private int instructionCounter = 0;
+
+	public static void main(String[] args) throws IOException {
+		new Day5().printParts();
+	}
+	
+	public int part1() throws IOException {
+		return execute(12, 2);
+	}
+
+	private int execute(int x, int y) throws IOException {
+		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day5.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
+		//program[1] = x;
+		//program[2] = y;
+		for(; executeInstruction(program, program[instructionCounter]); instructionCounter+=nParams(program[instructionCounter])+1);
+		return program[0];
+	}
+
+	/*private boolean executeInstruction(int[] program, int i, int instruction) {
+		switch(instruction) {
+			case 1: program[program[i+3]] = program[program[i+1]] + program[program[i+2]];
+			case 2: program[program[i+3]] = program[program[i+1]] * program[program[i+2]]; break;
+			case 99: return false;
+			default: throw new IllegalStateException("Something went wrong!");
+		}
+		
+		return true;
+	}*/
+	
+	private boolean executeInstruction(int[] program, int i, int instruction) {
+		System.out.println("Executing instruction "+instruction+" at i "+i);
+		if(instruction>99) 
+			return parseComplexInstruction(program, i, instruction);
+		else if(instruction == 99)
+			return false;
+		return execute(program, i, instruction);
+	}
+	
+	private boolean execute(int[] program, int i, int instruction) {
+		return execute(program, new int[NUM_MODES], i, instruction);
+	}
+
+	private boolean execute(int[] program, int[] method, int i, int instruction) {
+		int nParams = nParams(instruction);
+		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[i+nParams] : program[i+j]).toArray();
+		if(args.length>2) Arrays.stream(new int[]{2, 1}).filter(j -> method[j] == 0).map(j -> j == 2 ? 1 : 2).forEach(j -> args[j] = program[args[j]]);
+		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
+		return executeInstruction(program, args, instruction);
+	}
+	
+	/*static int reverseRange(int num, int from, int to) {
+	    return to - num + from - 1;
+	}*/
+	
+	private boolean executeInstruction(int[] program, int[] args, int instruction) {
+		switch(instruction) {
+			case 1: program[args[0]] = args[1] + args[2]; break;
+			case 2: program[args[0]] = args[1] * args[2]; break;
+			case 3: program[args[0]] = 1; break;
+			case 4: if(args[0]!=0) System.out.println(args[0]); break;
+			default: throw new IllegalStateException("Something went wrong!");
+		}
+		
+		return true;
+	}
+	
+	private boolean parseComplexInstruction(int[] program, int i, int instruction) {
+		int[] instructions = getInstructions(instruction);
+		int opcode = getOpCode(instructions);
+		System.out.println("Parsed as "+Arrays.toString(instructions)+" opcode "+opcode);
+		return execute(program, instructions, i, 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[] getParams(int[] program, int instruction, boolean parameterMode) {
+		int nParams = nParams(instruction);
+		IntStream params = IntStream.range(1,nParams+1).map(i -> program[i]);
+		if(parameterMode) params = 
+	}
+	
+	*/private int nParams(int instruction) {
+		switch(instruction) {
+			case 1: 
+			case 2: return 3;
+			case 3: 
+			case 4: return 1;
+			default: if(instruction>=99) return nParams(getOpCode(instruction));
+					 else throw new IllegalStateException("Something went wrong!");
+		}
+	}
+
+	@Override
+	public int part2() throws IOException {
+		return -1;
+	}
+
+}
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

From def6147a275006bd37aa9a239020743d8835b32f Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 5 Dec 2019 15:35:29 +0100
Subject: [PATCH 009/120] Cleanup day 5 code

---
 .../sbaars/adventofcode2019/days/Day5.java    | 70 +++++++------------
 1 file changed, 25 insertions(+), 45 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 1b0920b3..31543b07 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -19,70 +19,52 @@ public static void main(String[] args) throws IOException {
 	}
 	
 	public int part1() throws IOException {
-		return execute(12, 2);
+		return execute();
 	}
 
-	private int execute(int x, int y) throws IOException {
+	private int execute() throws IOException {
 		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day5.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
-		//program[1] = x;
-		//program[2] = y;
-		for(; executeInstruction(program, program[instructionCounter]); instructionCounter+=nParams(program[instructionCounter])+1);
-		return program[0];
+		int result;
+		for(; (result = executeInstruction(program, program[instructionCounter])) == -1; instructionCounter+=nParams(program[instructionCounter])+1);
+		return result;
 	}
 
-	/*private boolean executeInstruction(int[] program, int i, int instruction) {
-		switch(instruction) {
-			case 1: program[program[i+3]] = program[program[i+1]] + program[program[i+2]];
-			case 2: program[program[i+3]] = program[program[i+1]] * program[program[i+2]]; break;
-			case 99: return false;
-			default: throw new IllegalStateException("Something went wrong!");
-		}
-		
-		return true;
-	}*/
-	
-	private boolean executeInstruction(int[] program, int i, int instruction) {
-		System.out.println("Executing instruction "+instruction+" at i "+i);
+	private int executeInstruction(int[] program, int instruction) {
 		if(instruction>99) 
-			return parseComplexInstruction(program, i, instruction);
+			return parseComplexInstruction(program, instruction);
 		else if(instruction == 99)
-			return false;
-		return execute(program, i, instruction);
+			throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
+		return execute(program, instruction);
 	}
 	
-	private boolean execute(int[] program, int i, int instruction) {
-		return execute(program, new int[NUM_MODES], i, instruction);
+	private int execute(int[] program, int instruction) {
+		return execute(program, new int[NUM_MODES], instruction);
 	}
 
-	private boolean execute(int[] program, int[] method, int i, int instruction) {
+	private int execute(int[] program, int[] method, int instruction) {
 		int nParams = nParams(instruction);
-		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[i+nParams] : program[i+j]).toArray();
+		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
 		if(args.length>2) Arrays.stream(new int[]{2, 1}).filter(j -> method[j] == 0).map(j -> j == 2 ? 1 : 2).forEach(j -> args[j] = program[args[j]]);
 		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
 		return executeInstruction(program, args, instruction);
 	}
 	
-	/*static int reverseRange(int num, int from, int to) {
-	    return to - num + from - 1;
-	}*/
-	
-	private boolean executeInstruction(int[] program, int[] args, int instruction) {
+	private int executeInstruction(int[] program, int[] args, int instruction) {
 		switch(instruction) {
 			case 1: program[args[0]] = args[1] + args[2]; break;
 			case 2: program[args[0]] = args[1] * args[2]; break;
 			case 3: program[args[0]] = 1; break;
-			case 4: if(args[0]!=0) System.out.println(args[0]); break;
+			case 4: if(args[0]!=0) return args[0]; break;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
 		
-		return true;
+		return -1;
 	}
 	
-	private boolean parseComplexInstruction(int[] program, int i, int instruction) {
+	private int parseComplexInstruction(int[] program, int instruction) {
 		int[] instructions = getInstructions(instruction);
 		int opcode = getOpCode(instructions);
-		System.out.println("Parsed as "+Arrays.toString(instructions)+" opcode "+opcode);
-		return execute(program, instructions, i, opcode);
+		return execute(program, instructions, opcode);
 		
 	}
 	
@@ -103,18 +85,16 @@ private int[] getInstructions(int instruction) {
 		return instructions;
 	}
 	
-	/*private int[] getParams(int[] program, int instruction, boolean parameterMode) {
-		int nParams = nParams(instruction);
-		IntStream params = IntStream.range(1,nParams+1).map(i -> program[i]);
-		if(parameterMode) params = 
-	}
-	
-	*/private int nParams(int instruction) {
+	private int nParams(int instruction) {
 		switch(instruction) {
-			case 1: 
-			case 2: return 3;
 			case 3: 
 			case 4: 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!");
 		}

From 53531047bc44dddcd6462d994147f4ff6b64dcaa Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 5 Dec 2019 15:44:44 +0100
Subject: [PATCH 010/120] Refactoring

---
 .../sbaars/adventofcode2019/days/Day1.java    |  2 ++
 .../sbaars/adventofcode2019/days/Day2.java    | 29 +++++++++++--------
 .../sbaars/adventofcode2019/days/Day3.java    | 12 ++++----
 .../sbaars/adventofcode2019/days/Day4.java    | 11 ++++---
 .../sbaars/adventofcode2019/days/Day5.java    |  4 +--
 5 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day1.java b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
index 2ebdff09..fb2af57a 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
@@ -15,10 +15,12 @@ public static void main(String[] args) throws IOException
     	new Day1().printParts();
     }
 
+    @Override
 	public int part1() throws IOException {
 		return createNumberStream().map(this::getFuel).sum();
 	}
 	
+    @Override
 	public int part2() throws IOException {
 		return createNumberStream().map(this::getRequiredFuel).sum();
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index 4ecdb381..0417c528 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -13,9 +13,26 @@ public static void main(String[] args) throws IOException {
 		new Day2().printParts();
 	}
 	
+	@Override
 	public int part1() throws IOException {
 		return execute(12, 2);
 	}
+	
+	@Override
+	public int part2() throws IOException {
+		return bruteForceFindingNumber(19690720, 99);
+	}
+
+	private int bruteForceFindingNumber(int number, int bound) throws IOException {
+		for(int i = 0; i<bound;i++) {
+			for(int j = 0; j<bound; j++) {
+					if(execute(i, j) == number) {
+						return 100 * i + j;
+					}
+				}
+		}
+		return -1;
+	}
 
 	private int execute(int x, int y) throws IOException {
 		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day2.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
@@ -36,16 +53,4 @@ private boolean executeInstruction(int[] program, int i, int instruction) {
 		return true;
 	}
 
-	@Override
-	public int part2() throws IOException {
-		for(int i = 0; i<99;i++) {
-			for(int j = 0; j<99; j++) {
-					if(execute(i, j) == 19690720) {
-						return 100 * i + j;
-					}
-				}
-		}
-		return -1;
-	}
-
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 794bdc38..dade88db 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -22,14 +22,20 @@ private Day3() throws IOException {
 		this.intersect = calculateDistance(walks2, walkedLocations, true);
 	}
 	
-    public static void main(String[] args) throws IOException
+	public static void main(String[] args) throws IOException
     {
     	new Day3().printParts();
     }
 
+	@Override
 	public int part1() throws IOException {
 		return intersect.stream().mapToInt(e -> distance(e.point)).min().orElse(Integer.MAX_VALUE);
 	}
+	
+	@Override
+	public int part2() throws IOException {
+		return intersect.stream().mapToInt(e -> e.steps).min().orElse(Integer.MAX_VALUE);
+	}
 
 	private Set<Step> calculateDistance(Walk[] walks1, Set<Step> walkedLocations, boolean collect) {
 		Set<Step> intersectingLocations = new HashSet<>();
@@ -69,10 +75,6 @@ public int distance(Point p) {
 	private Walk[] mapToWalks(String string) {
 		return Arrays.stream(string.split(",")).map(Walk::new).toArray(Walk[]::new);
 	}
-
-	public int part2() throws IOException {
-		return intersect.stream().mapToInt(e -> e.steps).min().orElse(Integer.MAX_VALUE);
-	}
 	
 	class Walk {
 		private final Direction dir;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day4.java b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
index 5ec9ea2b..ce7ef287 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
@@ -18,6 +18,11 @@ public int part1() throws IOException {
 		return checkPasswords(false);
 	}
 	
+	@Override
+	public int 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();
 	}
@@ -45,12 +50,6 @@ public boolean meetsCriteria(int input, boolean checkGroup)
 	    return adjacentTheSame!=-2;
 	}
 
-
-	@Override
-	public int part2() throws IOException {
-		return checkPasswords(true);
-	}
-
 	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
index 31543b07..928ab867 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -9,8 +9,7 @@
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class Day5 implements Day, DoesFileOperations {
-	
-	boolean parameterMode = true;
+
 	private static int NUM_MODES = 3;
 	private int instructionCounter = 0;
 
@@ -18,6 +17,7 @@ public static void main(String[] args) throws IOException {
 		new Day5().printParts();
 	}
 	
+	@Override
 	public int part1() throws IOException {
 		return execute();
 	}

From 072dbd3feaa7e53636c042bc6869641ff50fa87a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 5 Dec 2019 15:51:19 +0100
Subject: [PATCH 011/120] Added additional cases for part 2

---
 .../sbaars/adventofcode2019/days/Day5.java    | 20 ++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 928ab867..2f3d23a3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -12,6 +12,7 @@ public class Day5 implements Day, DoesFileOperations {
 
 	private static int NUM_MODES = 3;
 	private int instructionCounter = 0;
+	private int part;
 
 	public static void main(String[] args) throws IOException {
 		new Day5().printParts();
@@ -19,6 +20,13 @@ public static void main(String[] args) throws IOException {
 	
 	@Override
 	public int part1() throws IOException {
+		part = 1;
+		return execute();
+	}
+	
+	@Override
+	public int part2() throws IOException {
+		part = 2;
 		return execute();
 	}
 
@@ -53,8 +61,12 @@ private int executeInstruction(int[] program, int[] args, int instruction) {
 		switch(instruction) {
 			case 1: program[args[0]] = args[1] + args[2]; break;
 			case 2: program[args[0]] = args[1] * args[2]; break;
-			case 3: program[args[0]] = 1; break;
+			case 3: program[args[0]] = part == 1 ? 1 : 5; break;
 			case 4: if(args[0]!=0) return args[0]; break;
+			case 5: if(args[1] != 0) instructionCounter = args[0]; break;
+			case 6: if(args[1] == 0) instructionCounter = args[0]; break;
+			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
+			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
 		
@@ -99,10 +111,4 @@ private int nParams(int instruction) {
 					 else throw new IllegalStateException("Something went wrong!");
 		}
 	}
-
-	@Override
-	public int part2() throws IOException {
-		return -1;
-	}
-
 }

From 92f8b2cce970b97047095ce7d8a8e8e7a5b3287d Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 5 Dec 2019 16:29:58 +0100
Subject: [PATCH 012/120] Finished day 5

---
 .../com/sbaars/adventofcode2019/days/Day5.java  | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 2f3d23a3..183d2c07 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -10,7 +10,7 @@
 
 public class Day5 implements Day, DoesFileOperations {
 
-	private static int NUM_MODES = 3;
+	private static final int NUM_MODES = 3;
 	private int instructionCounter = 0;
 	private int part;
 
@@ -27,13 +27,14 @@ public int part1() throws IOException {
 	@Override
 	public int part2() throws IOException {
 		part = 2;
+		instructionCounter = 0;
 		return execute();
 	}
 
 	private int execute() throws IOException {
 		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day5.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
 		int result;
-		for(; (result = executeInstruction(program, program[instructionCounter])) == -1; instructionCounter+=nParams(program[instructionCounter])+1);
+		while((result = executeInstruction(program, program[instructionCounter])) == -1);
 		return result;
 	}
 
@@ -52,8 +53,12 @@ private int execute(int[] program, int instruction) {
 	private int execute(int[] program, int[] method, int instruction) {
 		int nParams = nParams(instruction);
 		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
-		if(args.length>2) Arrays.stream(new int[]{2, 1}).filter(j -> method[j] == 0).map(j -> j == 2 ? 1 : 2).forEach(j -> args[j] = program[args[j]]);
+		if(args.length>=2) {
+			if(method[2] == 0) args[1] = program[args[1]];
+			if(args.length>=3 && method[1] == 0) args[2] = program[args[2]];
+		}
 		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
+		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
 		return executeInstruction(program, args, instruction);
 	}
 	
@@ -63,13 +68,13 @@ private int executeInstruction(int[] program, int[] args, int instruction) {
 			case 2: program[args[0]] = args[1] * args[2]; break;
 			case 3: program[args[0]] = part == 1 ? 1 : 5; break;
 			case 4: if(args[0]!=0) return args[0]; break;
-			case 5: if(args[1] != 0) instructionCounter = args[0]; break;
-			case 6: if(args[1] == 0) instructionCounter = args[0]; break;
+			case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
+			case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
 			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
 			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
-		
+		instructionCounter+=nParams(instruction) + 1;
 		return -1;
 	}
 	

From 20824b20f542ff3328a068ee8cdb15d1a960f7a8 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 6 Dec 2019 06:14:56 +0100
Subject: [PATCH 013/120] Part 1 Day 6

---
 .../sbaars/adventofcode2019/days/Day6.java    |   57 +
 .../sbaars/adventofcode2019/util/ListMap.java |   65 +
 src/main/resources/day6.txt                   | 1294 +++++++++++++++++
 3 files changed, 1416 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day6.java
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/util/ListMap.java
 create mode 100644 src/main/resources/day6.txt

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..2d25ee0f
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -0,0 +1,57 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+import com.sbaars.adventofcode2019.util.ListMap;
+
+public class Day6 implements Day, DoesFileOperations
+{	
+    public static void main(String[] args) throws IOException
+    {
+    	new Day6().printParts();
+    }
+
+    @Override
+	public int part1() throws IOException {
+    	ListMap<String, String> orbits = new ListMap<>();
+    	String[] nums = createNumberStream();
+    	for(String num : nums) {
+    		String[] parts = num.split("\\)");
+    		orbits.addTo(parts[0], parts[1]);
+    	}
+    	AtomicInteger o = new AtomicInteger();
+    	extracted(orbits, o);
+		return o.get();
+	}
+
+	private void extracted(ListMap<String, String> orbits, AtomicInteger o) {
+		for(Entry<String, List<String>> entry : orbits.entrySet()) {
+    		extracted(orbits, o, entry.getValue());
+    	}
+	}
+
+	private void extracted(ListMap<String, String> orbits, AtomicInteger o, List<String> entry) {
+		for(String str : entry) {
+			o.incrementAndGet();
+			if(orbits.containsKey(str)) {
+				extracted(orbits, o, orbits.get(str));
+			}
+		}
+	}
+	
+    @Override
+	public int part2() throws IOException {
+		return 0;
+	}
+
+	private String[] createNumberStream() throws IOException {
+		return Arrays.stream(getFileAsString(new File(Day6.class.getClassLoader().getResource("day6.txt").getFile())).split(System.lineSeparator())).toArray(String[]::new);
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/ListMap.java b/src/main/java/com/sbaars/adventofcode2019/util/ListMap.java
new file mode 100644
index 00000000..0ae585d9
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/util/ListMap.java
@@ -0,0 +1,65 @@
+package com.sbaars.adventofcode2019.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+public class ListMap<K, V> extends HashMap<K, List<V>> {
+	/**
+	 * 
+	 */
+	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<V>> m) {
+		super(m);
+	}
+	
+	public List<V> addTo(K key, V value) {
+		List<V> l;
+		if(super.containsKey(key)) {
+			l = super.get(key); 
+		} else l = new ArrayList<>();
+		l.add(value);
+        return super.put(key, l);
+    }
+	
+	public List<V> addTo(K key, V[] value) {
+		List<V> 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<V> get(Object key){
+		if(!super.containsKey(key))
+			super.put((K) key, new ArrayList<>());
+		return super.get(key);
+	}
+	
+	public Entry<K, List<V>> getEntryForValue(V i) {
+		System.out.println(Arrays.toString(values().toArray()));
+		Optional<Entry<K, List<V>>> 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/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

From aede704d4ace572f9fde3d0989d5218d45be3d99 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 6 Dec 2019 06:35:15 +0100
Subject: [PATCH 014/120] Day 6 Part 2

---
 .../sbaars/adventofcode2019/days/Day6.java    | 48 ++++++++++++++++++-
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
index 2d25ee0f..bf5533f9 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -2,6 +2,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map.Entry;
@@ -13,6 +14,9 @@
 
 public class Day6 implements Day, DoesFileOperations
 {	
+	
+	ListMap<String, String> orbits = new ListMap<>();
+	
     public static void main(String[] args) throws IOException
     {
     	new Day6().printParts();
@@ -20,7 +24,6 @@ public static void main(String[] args) throws IOException
 
     @Override
 	public int part1() throws IOException {
-    	ListMap<String, String> orbits = new ListMap<>();
     	String[] nums = createNumberStream();
     	for(String num : nums) {
     		String[] parts = num.split("\\)");
@@ -48,9 +51,50 @@ private void extracted(ListMap<String, String> orbits, AtomicInteger o, List<Str
 	
     @Override
 	public int part2() throws IOException {
-		return 0;
+    	
+		return goFrom("YOU", "SAN");
+	}
+    
+    public int goFrom(String s1, String s2) {
+    	AtomicInteger steps = new AtomicInteger();
+    	step(s1, 0);
+    	return 0;
+    }
+    
+    List<String> been = new ArrayList<>();
+    
+    private void step(String s1, int depth) {
+    	if(been.contains(s1))
+    		return;
+    	been.add(s1);
+    	List<String> str = collectAll(s1);
+    	//System.out.println(Arrays.toString(str.toArray()));
+    	if(str.contains("SAN")) {
+    		System.out.println(depth+1);
+    		//System.exit(1);
+    	}
+    	//steps.incrementAndGet();
+    	for(String s : str) {
+    		step(s, depth + 1);
+    	}
 	}
 
+	private List<String> collectAll(String s1) {
+    	List<String> s = findOrbit(s1);
+    	s.addAll(orbits.get(s1));
+		return s;
+	}
+
+	public List<String> findOrbit(String orbitValue) {
+		List<String> orbit = new ArrayList<>();
+    	for(Entry<String, List<String>> entry : orbits.entrySet()) {
+    		if(entry.getValue().contains(orbitValue)) {
+    			orbit.add(entry.getKey());
+    		}
+    	}
+    	return orbit;
+    }
+
 	private String[] createNumberStream() throws IOException {
 		return Arrays.stream(getFileAsString(new File(Day6.class.getClassLoader().getResource("day6.txt").getFile())).split(System.lineSeparator())).toArray(String[]::new);
 	}

From 7bfb4c99cb67ffa9f8381ec25b66ef46d47c9f0e Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 6 Dec 2019 06:45:19 +0100
Subject: [PATCH 015/120] Refactor day 6

---
 .../sbaars/adventofcode2019/days/Day6.java    | 50 +++++++------------
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
index bf5533f9..25d5fd0c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -24,59 +24,47 @@ public static void main(String[] args) throws IOException
 
     @Override
 	public int part1() throws IOException {
-    	String[] nums = createNumberStream();
+    	String[] nums = createOrbitArray();
     	for(String num : nums) {
     		String[] parts = num.split("\\)");
     		orbits.addTo(parts[0], parts[1]);
     	}
     	AtomicInteger o = new AtomicInteger();
-    	extracted(orbits, o);
+    	for(Entry<String, List<String>> entry : orbits.entrySet())
+    		countOrbitsInList(orbits, o, entry.getValue());
 		return o.get();
 	}
 
-	private void extracted(ListMap<String, String> orbits, AtomicInteger o) {
-		for(Entry<String, List<String>> entry : orbits.entrySet()) {
-    		extracted(orbits, o, entry.getValue());
-    	}
-	}
-
-	private void extracted(ListMap<String, String> orbits, AtomicInteger o, List<String> entry) {
+	private void countOrbitsInList(ListMap<String, String> orbits, AtomicInteger o, List<String> entry) {
 		for(String str : entry) {
 			o.incrementAndGet();
 			if(orbits.containsKey(str)) {
-				extracted(orbits, o, orbits.get(str));
+				countOrbitsInList(orbits, o, orbits.get(str));
 			}
 		}
 	}
 	
     @Override
 	public int part2() throws IOException {
-    	
-		return goFrom("YOU", "SAN");
+		return findRoute("YOU", "SAN");
 	}
     
-    public int goFrom(String s1, String s2) {
-    	AtomicInteger steps = new AtomicInteger();
-    	step(s1, 0);
-    	return 0;
+    private int findRoute(String from, String to) {
+    	return findRoute(from, to, new ArrayList<>(), 0);
     }
     
-    List<String> been = new ArrayList<>();
-    
-    private void step(String s1, int depth) {
-    	if(been.contains(s1))
-    		return;
-    	been.add(s1);
-    	List<String> str = collectAll(s1);
-    	//System.out.println(Arrays.toString(str.toArray()));
-    	if(str.contains("SAN")) {
-    		System.out.println(depth+1);
-    		//System.exit(1);
-    	}
-    	//steps.incrementAndGet();
+    private int findRoute(String from, String to, List<String> visited, int depth) {
+    	if(visited.contains(from))
+    		return 0;
+    	visited.add(from);
+    	List<String> str = collectAll(from);
+    	if(str.contains(to))
+    		return depth-1;
     	for(String s : str) {
-    		step(s, depth + 1);
+    		int findRoute = findRoute(s, to, visited, depth + 1);
+			if(findRoute>0) return findRoute;
     	}
+    	return -1;
 	}
 
 	private List<String> collectAll(String s1) {
@@ -95,7 +83,7 @@ public List<String> findOrbit(String orbitValue) {
     	return orbit;
     }
 
-	private String[] createNumberStream() throws IOException {
+	private String[] createOrbitArray() throws IOException {
 		return Arrays.stream(getFileAsString(new File(Day6.class.getClassLoader().getResource("day6.txt").getFile())).split(System.lineSeparator())).toArray(String[]::new);
 	}
 }

From 694e74aff42a403b6c49da5823bb273ea43aa4ac Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 07:01:36 +0100
Subject: [PATCH 016/120] Day 7 Part 1

---
 .../sbaars/adventofcode2019/days/Day7.java    | 153 ++++++++++++++++++
 src/main/resources/day7-2.txt                 |   1 +
 src/main/resources/day7.txt                   |   1 +
 3 files changed, 155 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day7.java
 create mode 100644 src/main/resources/day7-2.txt
 create mode 100644 src/main/resources/day7.txt

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..5dadae9a
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -0,0 +1,153 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day7 implements Day, DoesFileOperations {
+
+	private static final int NUM_MODES = 3;
+	private int instructionCounter = 0;
+	private int part;
+	int phase = 0;
+	boolean isFirst = true;
+
+	public static void main(String[] args) throws IOException {
+		new Day7().printParts();
+	}
+	int lastVal = -1;
+	
+	@Override
+	public int part1() throws IOException {
+		Set<List<Integer>> shuffles = getShuffles(Arrays.asList(0,1,2,3,4));
+		List<Integer> results = new ArrayList<>();
+		//List<Integer> shuffle = Arrays.asList(4,3,2,1,0);
+		for(List<Integer> shuffle : shuffles) {
+			lastVal = -1;
+			part = 0;
+			for(Integer i : shuffle) {
+				isFirst = true;
+				phase = i;
+				try {
+					lastVal = execute();
+				} catch(Exception e) {
+					e.printStackTrace();
+				}
+				part++;
+			}
+			results.add(lastVal);
+			
+		}
+		return results.stream().mapToInt(e -> e).max().getAsInt();
+	}
+	
+	public Set<List<Integer>> getShuffles(List<Integer> ints){
+		Set<List<Integer>> sets = new HashSet<List<Integer>>();
+		for(int i = 0; i<100000; i++) {
+			Collections.shuffle(ints);
+			sets.add(new ArrayList<>(ints));
+		}
+		return sets;
+	}
+	
+	@Override
+	public int part2() throws IOException {
+		return 0;
+	}
+
+	private int execute() throws IOException {
+		instructionCounter = 0;
+		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
+		int result;
+		while((result = executeInstruction(program, program[instructionCounter])) == -1);
+		return result;
+	}
+
+	private int executeInstruction(int[] program, int instruction) {
+		if(instruction>99) 
+			return parseComplexInstruction(program, instruction);
+		else if(instruction == 99)
+			throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
+		return execute(program, instruction);
+	}
+	
+	private int execute(int[] program, int instruction) {
+		return execute(program, new int[NUM_MODES], instruction);
+	}
+
+	private int execute(int[] program, int[] method, int instruction) {
+		int nParams = nParams(instruction);
+		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
+		if(args.length>=2) {
+			if(method[2] == 0) args[1] = program[args[1]];
+			if(args.length>=3 && method[1] == 0) args[2] = program[args[2]];
+		}
+		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
+		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
+		return executeInstruction(program, args, instruction);
+	}
+	
+	private int executeInstruction(int[] program, int[] args, int instruction) {
+		switch(instruction) {
+			case 1: program[args[0]] = args[1] + args[2]; break;
+			case 2: program[args[0]] = args[1] * args[2]; break;
+			case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal); isFirst = false; break;
+			case 4: /*if(args[0]!=0)*/ return args[0];/*lastVal=args[0];*/  //break;
+			case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
+			case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
+			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
+			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
+			default: throw new IllegalStateException("Something went wrong!");
+		}
+		instructionCounter+=nParams(instruction) + 1;
+		return -1;
+	}
+	
+	private int parseComplexInstruction(int[] program, int instruction) {
+		int[] instructions = getInstructions(instruction);
+		int opcode = getOpCode(instructions);
+		return execute(program, instructions, 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 3: 
+			case 4: 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);
+		}
+	}
+}
diff --git a/src/main/resources/day7-2.txt b/src/main/resources/day7-2.txt
new file mode 100644
index 00000000..993e2e04
--- /dev/null
+++ b/src/main/resources/day7-2.txt
@@ -0,0 +1 @@
+3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0
\ 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

From 17b9014676e83f569ed7cd3dbf5c96558e46be6c Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 07:49:38 +0100
Subject: [PATCH 017/120] ...

---
 .../sbaars/adventofcode2019/days/Day7.java    | 115 ++++++++++--------
 src/main/resources/7-4.txt                    |   1 +
 src/main/resources/day7-3.txt                 |   1 +
 3 files changed, 65 insertions(+), 52 deletions(-)
 create mode 100644 src/main/resources/7-4.txt
 create mode 100644 src/main/resources/day7-3.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 5dadae9a..72b4c5aa 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -25,40 +25,50 @@ public static void main(String[] args) throws IOException {
 		new Day7().printParts();
 	}
 	int lastVal = -1;
-	
+
 	@Override
 	public int part1() throws IOException {
-		Set<List<Integer>> shuffles = getShuffles(Arrays.asList(0,1,2,3,4));
+		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
 		List<Integer> results = new ArrayList<>();
-		//List<Integer> shuffle = Arrays.asList(4,3,2,1,0);
-		for(List<Integer> shuffle : shuffles) {
-			lastVal = -1;
-			part = 0;
-			for(Integer i : shuffle) {
-				isFirst = true;
-				phase = i;
-				try {
-					lastVal = execute();
-				} catch(Exception e) {
-					e.printStackTrace();
-				}
-				part++;
+		List<Integer> shuffle = Arrays.asList(9,8,7,6,5);
+		//for(List<Integer> shuffle : shuffles) {
+		lastVal = 0;
+		part = 0;
+		for(Integer i : shuffle) {
+			isFirst = true;
+			phase = i;
+			try {
+				execute();
+			} catch(Exception e) {
+				e.printStackTrace();
 			}
-			results.add(lastVal);
-			
 		}
+		results.add(lastVal);
+
+		//}
 		return results.stream().mapToInt(e -> e).max().getAsInt();
 	}
-	
-	public Set<List<Integer>> getShuffles(List<Integer> ints){
-		Set<List<Integer>> sets = new HashSet<List<Integer>>();
-		for(int i = 0; i<100000; i++) {
-			Collections.shuffle(ints);
-			sets.add(new ArrayList<>(ints));
+
+	public <E> List<List<E>> generatePerm(List<E> original) {
+		if (original.isEmpty()) {
+			List<List<E>> result = new ArrayList<>(); 
+			result.add(new ArrayList<E>()); 
+			return result; 
 		}
-		return sets;
+		E firstElement = original.remove(0);
+		List<List<E>> returnValue = new ArrayList<>();
+		List<List<E>> permutations = generatePerm(original);
+		for (List<E> smallerPermutated : permutations) {
+			for (int index=0; index <= smallerPermutated.size(); index++) {
+				List<E> temp = new ArrayList<>(smallerPermutated);
+				temp.add(index, firstElement);
+				returnValue.add(temp);
+			}
+		}
+		return returnValue;
 	}
-	
+
+
 	@Override
 	public int part2() throws IOException {
 		return 0;
@@ -66,7 +76,7 @@ public int part2() throws IOException {
 
 	private int execute() throws IOException {
 		instructionCounter = 0;
-		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
+		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7-3.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
 		int result;
 		while((result = executeInstruction(program, program[instructionCounter])) == -1);
 		return result;
@@ -76,10 +86,11 @@ private int executeInstruction(int[] program, int instruction) {
 		if(instruction>99) 
 			return parseComplexInstruction(program, instruction);
 		else if(instruction == 99)
-			throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
+			return 0;
+		//throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
 		return execute(program, instruction);
 	}
-	
+
 	private int execute(int[] program, int instruction) {
 		return execute(program, new int[NUM_MODES], instruction);
 	}
@@ -95,30 +106,30 @@ private int execute(int[] program, int[] method, int instruction) {
 		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
 		return executeInstruction(program, args, instruction);
 	}
-	
+
 	private int executeInstruction(int[] program, int[] args, int instruction) {
 		switch(instruction) {
-			case 1: program[args[0]] = args[1] + args[2]; break;
-			case 2: program[args[0]] = args[1] * args[2]; break;
-			case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal); isFirst = false; break;
-			case 4: /*if(args[0]!=0)*/ return args[0];/*lastVal=args[0];*/  //break;
-			case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
-			case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
-			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
-			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
-			default: throw new IllegalStateException("Something went wrong!");
+		case 1: program[args[0]] = args[1] + args[2]; break;
+		case 2: program[args[0]] = args[1] * args[2]; break;
+		case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal);if(!isFirst) part++; isFirst = false; break;
+		case 4: /*if(args[0]!=0)*/ lastVal = args[0];/*lastVal=args[0];*/  break;
+		case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
+		case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
+		case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
+		case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
+		default: throw new IllegalStateException("Something went wrong!");
 		}
 		instructionCounter+=nParams(instruction) + 1;
 		return -1;
 	}
-	
+
 	private int parseComplexInstruction(int[] program, int instruction) {
 		int[] instructions = getInstructions(instruction);
 		int opcode = getOpCode(instructions);
 		return execute(program, instructions, opcode);
-		
+
 	}
-	
+
 	private int getOpCode(int instruction) {
 		return getOpCode(getInstructions(instruction));
 	}
@@ -135,19 +146,19 @@ private int[] getInstructions(int instruction) {
 		}
 		return instructions;
 	}
-	
+
 	private int nParams(int instruction) {
 		switch(instruction) {
-			case 3: 
-			case 4: 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);
+		case 3: 
+		case 4: 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);
 		}
 	}
 }
diff --git a/src/main/resources/7-4.txt b/src/main/resources/7-4.txt
new file mode 100644
index 00000000..5ed292ba
--- /dev/null
+++ b/src/main/resources/7-4.txt
@@ -0,0 +1 @@
+3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
\ No newline at end of file
diff --git a/src/main/resources/day7-3.txt b/src/main/resources/day7-3.txt
new file mode 100644
index 00000000..4363e8ee
--- /dev/null
+++ b/src/main/resources/day7-3.txt
@@ -0,0 +1 @@
+3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
\ No newline at end of file

From de14b7cca8ef15c58f2200ac7546ebd32bffaba3 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 08:48:54 +0100
Subject: [PATCH 018/120] Day 7 part 2

---
 .../sbaars/adventofcode2019/days/Day7.java    | 44 ++++++++++++-------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 72b4c5aa..83991ff7 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -25,27 +25,36 @@ public static void main(String[] args) throws IOException {
 		new Day7().printParts();
 	}
 	int lastVal = -1;
+	
+	boolean done = false;
 
 	@Override
 	public int part1() throws IOException {
-		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
+		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
+		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
 		List<Integer> results = new ArrayList<>();
-		List<Integer> shuffle = Arrays.asList(9,8,7,6,5);
-		//for(List<Integer> shuffle : shuffles) {
+		//List<Integer> shuffle = Arrays.asList(9,8,7,6,5);
+		for(List<Integer> shuffle : shuffles) {
 		lastVal = 0;
 		part = 0;
+		int[][] programs = new int[shuffle.size()][program.length];
+		for(int i = 0; i<programs.length; i++) {
+			for(int j = 0; j<program.length; j++) {
+				programs[i][j] = program[j];
+			}
+		}
+		int[] instructionCounters = new int[5];
+		done = false;
+		while(!done) {
 		for(Integer i : shuffle) {
-			isFirst = true;
 			phase = i;
-			try {
-				execute();
-			} catch(Exception e) {
-				e.printStackTrace();
-			}
+			lastVal = executeProgram(programs[i-5], instructionCounters[i-5]);
+			instructionCounters[i-5] = instructionCounter+2;
+		}
 		}
 		results.add(lastVal);
 
-		//}
+		}
 		return results.stream().mapToInt(e -> e).max().getAsInt();
 	}
 
@@ -74,9 +83,10 @@ public int part2() throws IOException {
 		return 0;
 	}
 
-	private int execute() throws IOException {
-		instructionCounter = 0;
-		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7-3.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
+	private int executeProgram(int[] program, int c) throws IOException {
+		isFirst = c == 0;
+		instructionCounter = c;
+		// = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7-3.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
 		int result;
 		while((result = executeInstruction(program, program[instructionCounter])) == -1);
 		return result;
@@ -85,8 +95,10 @@ private int execute() throws IOException {
 	private int executeInstruction(int[] program, int instruction) {
 		if(instruction>99) 
 			return parseComplexInstruction(program, instruction);
-		else if(instruction == 99)
-			return 0;
+		else if(instruction == 99) {
+			done = true;
+			return lastVal;
+		}
 		//throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
 		return execute(program, instruction);
 	}
@@ -112,7 +124,7 @@ private int executeInstruction(int[] program, int[] args, int instruction) {
 		case 1: program[args[0]] = args[1] + args[2]; break;
 		case 2: program[args[0]] = args[1] * args[2]; break;
 		case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal);if(!isFirst) part++; isFirst = false; break;
-		case 4: /*if(args[0]!=0)*/ lastVal = args[0];/*lastVal=args[0];*/  break;
+		case 4: /*if(args[0]!=0)lastVal=args[0]; */return args[0];/*lastVal=args[0];*/  //break;
 		case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
 		case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
 		case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;

From dba38328a2381cce2e3d5b3c705f7c282d375a79 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 09:03:10 +0100
Subject: [PATCH 019/120] Put the two parts in their appropriate places

I'll refactor later
---
 .../sbaars/adventofcode2019/days/Day7.java    | 71 ++++++++++++-------
 1 file changed, 46 insertions(+), 25 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 83991ff7..f202e9f3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -21,38 +21,65 @@ public class Day7 implements Day, DoesFileOperations {
 	int phase = 0;
 	boolean isFirst = true;
 
+	int[] startState;
+
+	public Day7() throws IOException {
+		startState = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
+	}
+
 	public static void main(String[] args) throws IOException {
 		new Day7().printParts();
 	}
 	int lastVal = -1;
-	
+
 	boolean done = false;
 
 	@Override
 	public int part1() throws IOException {
-		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
+		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
+		List<Integer> results = new ArrayList<>();
+		for(List<Integer> shuffle : shuffles) {
+			lastVal = -1;
+			part = 0;
+			for(Integer i : shuffle) {
+				int[] program = new int[startState.length];
+				for(int j = 0; j<startState.length; j++) {
+					program[j] = startState[j];
+				}
+				phase = i;
+				lastVal = executeProgram(program, 0);
+				part++;
+			}
+			results.add(lastVal);
+
+		}
+		return results.stream().mapToInt(e -> e).max().getAsInt();
+	}
+
+	@Override
+	public int part2() throws IOException {
 		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
 		List<Integer> results = new ArrayList<>();
 		//List<Integer> shuffle = Arrays.asList(9,8,7,6,5);
 		for(List<Integer> shuffle : shuffles) {
-		lastVal = 0;
-		part = 0;
-		int[][] programs = new int[shuffle.size()][program.length];
-		for(int i = 0; i<programs.length; i++) {
-			for(int j = 0; j<program.length; j++) {
-				programs[i][j] = program[j];
+			lastVal = 0;
+			part = 0;
+			int[][] programs = new int[shuffle.size()][startState.length];
+			for(int i = 0; i<programs.length; i++) {
+				for(int j = 0; j<startState.length; j++) {
+					programs[i][j] = startState[j];
+				}
 			}
-		}
-		int[] instructionCounters = new int[5];
-		done = false;
-		while(!done) {
-		for(Integer i : shuffle) {
-			phase = i;
-			lastVal = executeProgram(programs[i-5], instructionCounters[i-5]);
-			instructionCounters[i-5] = instructionCounter+2;
-		}
-		}
-		results.add(lastVal);
+			int[] instructionCounters = new int[5];
+			done = false;
+			while(!done) {
+				for(Integer i : shuffle) {
+					phase = i;
+					lastVal = executeProgram(programs[i-5], instructionCounters[i-5]);
+					instructionCounters[i-5] = instructionCounter+2;
+				}
+			}
+			results.add(lastVal);
 
 		}
 		return results.stream().mapToInt(e -> e).max().getAsInt();
@@ -77,12 +104,6 @@ public <E> List<List<E>> generatePerm(List<E> original) {
 		return returnValue;
 	}
 
-
-	@Override
-	public int part2() throws IOException {
-		return 0;
-	}
-
 	private int executeProgram(int[] program, int c) throws IOException {
 		isFirst = c == 0;
 		instructionCounter = c;

From 0c4cb67ca5f21fba73301ee1d146dbd55892bcf2 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 09:07:43 +0100
Subject: [PATCH 020/120] Minor refactorings for day 7

---
 .../sbaars/adventofcode2019/days/Day7.java    | 21 ++++++++-----------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index f202e9f3..723734f3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -18,10 +18,11 @@ public class Day7 implements Day, DoesFileOperations {
 	private static final int NUM_MODES = 3;
 	private int instructionCounter = 0;
 	private int part;
-	int phase = 0;
-	boolean isFirst = true;
-
-	int[] startState;
+	private int phase = 0;
+	private boolean isFirst = true;
+	private int[] startState;
+	private int lastVal = -1;
+	private boolean done = false;
 
 	public Day7() throws IOException {
 		startState = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
@@ -30,15 +31,12 @@ public Day7() throws IOException {
 	public static void main(String[] args) throws IOException {
 		new Day7().printParts();
 	}
-	int lastVal = -1;
-
-	boolean done = false;
 
 	@Override
 	public int part1() throws IOException {
-		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
+		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
 		List<Integer> results = new ArrayList<>();
-		for(List<Integer> shuffle : shuffles) {
+		for(List<Integer> shuffle : permutations) {
 			lastVal = -1;
 			part = 0;
 			for(Integer i : shuffle) {
@@ -58,10 +56,9 @@ public int part1() throws IOException {
 
 	@Override
 	public int part2() throws IOException {
-		List<List<Integer>> shuffles = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
+		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
 		List<Integer> results = new ArrayList<>();
-		//List<Integer> shuffle = Arrays.asList(9,8,7,6,5);
-		for(List<Integer> shuffle : shuffles) {
+		for(List<Integer> shuffle : permutations) {
 			lastVal = 0;
 			part = 0;
 			int[][] programs = new int[shuffle.size()][startState.length];

From 073902d5500019b978253be3619916f213a1bc2e Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 19:52:38 +0100
Subject: [PATCH 021/120] Separating IntCode Computer

---
 .../intcode/IntcodeComputer.java              | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
new file mode 100644
index 00000000..b5bb81b6
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -0,0 +1,110 @@
+package com.sbaars.adventofcode2019.intcode;
+
+import java.io.IOException;
+import java.util.stream.IntStream;
+
+public class IntcodeComputer extends Thread {
+	int[] program;
+	int instructionCounter;
+	
+	public IntcodeComputer(int day) {
+		
+	}
+	
+	
+	
+	@Override
+	public void run() {
+		
+	}
+	
+	private int executeProgram(int[] program, int c) throws IOException {
+		isFirst = c == 0;
+		int result;
+		while((result = executeInstruction(program, program[instructionCounter])) == -1);
+		return result;
+	}
+
+	private int executeInstruction(int[] program, int instruction) {
+		if(instruction>99) 
+			return parseComplexInstruction(program, instruction);
+		else if(instruction == 99) {
+			done = true;
+			return lastVal;
+		}
+		//throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
+		return execute(program, instruction);
+	}
+
+	private int execute(int[] program, int instruction) {
+		return execute(program, new int[NUM_MODES], instruction);
+	}
+
+	private int execute(int[] program, int[] method, int instruction) {
+		int nParams = nParams(instruction);
+		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
+		if(args.length>=2) {
+			if(method[2] == 0) args[1] = program[args[1]];
+			if(args.length>=3 && method[1] == 0) args[2] = program[args[2]];
+		}
+		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
+		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
+		return executeInstruction(program, args, instruction);
+	}
+
+	
+	private int executeInstruction(int[] program, int[] args, int instruction) {
+		switch(instruction) {
+		case 1: program[args[0]] = args[1] + args[2]; break;
+		case 2: program[args[0]] = args[1] * args[2]; break;
+		case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal);if(!isFirst) part++; isFirst = false; break;
+		case 4: return args[0];
+		case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
+		case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
+		case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
+		case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
+		default: throw new IllegalStateException("Something went wrong!");
+		}
+		instructionCounter+=nParams(instruction) + 1;
+		return -1;
+	}
+	
+	private int parseComplexInstruction(int[] program, int instruction) {
+		int[] instructions = getInstructions(instruction);
+		int opcode = getOpCode(instructions);
+		return execute(program, instructions, 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 3: 
+			case 4: 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);
+		}
+	}
+}

From e083c3ad521713055c14c4c107cbb49656ef2961 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 19:57:07 +0100
Subject: [PATCH 022/120] Refactoring interface

---
 .../util/DoesFileOperations.java              | 50 ++-----------------
 1 file changed, 3 insertions(+), 47 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java b/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
index 3a90b468..d1e16d17 100644
--- a/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
+++ b/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
@@ -4,58 +4,14 @@
 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));
-	}
-	
-	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);
-	    }
+		return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
 	}
 	
-	public default boolean delete(File dir) {
-	    if (dir.isDirectory()) {
-	        String[] children = dir.list();
-	        for (int i=0; i<children.length; i++) {
-	            boolean success = delete(new File(dir, children[i]));
-	            if (!success) {
-	                return false;
-	            }
-	        }
-	    }
-	    return dir.delete();
+	public default String getResourceAsString(String resource) throws IOException {
+		return getFileAsString(new File(DoesFileOperations.class.getClassLoader().getResource(resource).getFile()));
 	}
-
-
 }
\ No newline at end of file

From d15c8e4b4fb9ff4333b51fcb818f18554ef0e312 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 20:02:14 +0100
Subject: [PATCH 023/120] Refactored file retrieval

---
 .../com/sbaars/adventofcode2019/common/Day.java   |  8 +++++++-
 .../com/sbaars/adventofcode2019/days/Day1.java    |  6 ++----
 .../com/sbaars/adventofcode2019/days/Day2.java    |  3 +--
 .../com/sbaars/adventofcode2019/days/Day3.java    |  3 +--
 .../com/sbaars/adventofcode2019/days/Day5.java    |  3 +--
 .../com/sbaars/adventofcode2019/days/Day6.java    |  3 +--
 .../com/sbaars/adventofcode2019/days/Day7.java    |  5 +----
 .../adventofcode2019/intcode/IntcodeComputer.java | 15 ++++++++-------
 8 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Day.java b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
index caf3ee9d..080fb04f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Day.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
@@ -2,7 +2,9 @@
 
 import java.io.IOException;
 
-public interface Day {
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public interface Day extends DoesFileOperations {
 	public int part1() throws IOException;
 	public int part2() throws IOException;
 	
@@ -10,4 +12,8 @@ public default void printParts() throws IOException {
 		System.out.println("Part 1 = "+part1());
 		System.out.println("Part 2 = "+part2());
 	}
+	
+	public default String readDay(int day) throws IOException {
+		return getResourceAsString("day"+day+".txt");
+	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day1.java b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
index fb2af57a..c639cd9b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
@@ -1,14 +1,12 @@
 package com.sbaars.adventofcode2019.days;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day1 implements Day, DoesFileOperations
+public class Day1 implements Day
 {	
     public static void main(String[] args) throws IOException
     {
@@ -26,7 +24,7 @@ public int part2() throws IOException {
 	}
 
 	private IntStream createNumberStream() throws IOException {
-		return Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day1.txt").getFile())).split(System.lineSeparator())).mapToInt(Integer::parseInt);
+		return Arrays.stream(readDay(1).split(System.lineSeparator())).mapToInt(Integer::parseInt);
 	}
 	
 	private int getRequiredFuel(int mass) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index 0417c528..4508b9a3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -1,6 +1,5 @@
 package com.sbaars.adventofcode2019.days;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 
@@ -35,7 +34,7 @@ private int bruteForceFindingNumber(int number, int bound) throws IOException {
 	}
 
 	private int execute(int x, int y) throws IOException {
-		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day2.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
+		int[] program = Arrays.stream(readDay(2).split(",")).mapToInt(Integer::parseInt).toArray();
 		program[1] = x;
 		program[2] = y;
 		for(int i = 0; executeInstruction(program, i, program[i]); i+=4);
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index dade88db..fe3d90f1 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -1,7 +1,6 @@
 package com.sbaars.adventofcode2019.days;
 
 import java.awt.Point;
-import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -15,7 +14,7 @@ public class Day3 implements Day, DoesFileOperations
 	private Set<Step> intersect;
 	
 	private Day3() throws IOException {
-		String[] strings = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day3.txt").getFile())).split(System.lineSeparator())).toArray(String[]::new);
+		String[] strings = Arrays.stream(readDay(3).split(System.lineSeparator())).toArray(String[]::new);
 		Walk[] walks1 = mapToWalks(strings[0]), walks2 = mapToWalks(strings[1]);
 		Set<Step> walkedLocations = new HashSet<>();
 		calculateDistance(walks1, walkedLocations, false);
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 183d2c07..ead5ef56 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -1,6 +1,5 @@
 package com.sbaars.adventofcode2019.days;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.stream.IntStream;
@@ -32,7 +31,7 @@ public int part2() throws IOException {
 	}
 
 	private int execute() throws IOException {
-		int[] program = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day5.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();;
+		int[] program = Arrays.stream(readDay(5).split(",")).mapToInt(Integer::parseInt).toArray();;
 		int result;
 		while((result = executeInstruction(program, program[instructionCounter])) == -1);
 		return result;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
index 25d5fd0c..87a900df 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -1,6 +1,5 @@
 package com.sbaars.adventofcode2019.days;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -84,6 +83,6 @@ public List<String> findOrbit(String orbitValue) {
     }
 
 	private String[] createOrbitArray() throws IOException {
-		return Arrays.stream(getFileAsString(new File(Day6.class.getClassLoader().getResource("day6.txt").getFile())).split(System.lineSeparator())).toArray(String[]::new);
+		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
index 723734f3..fb95f1e3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -4,10 +4,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
@@ -142,7 +139,7 @@ private int executeInstruction(int[] program, int[] args, int instruction) {
 		case 1: program[args[0]] = args[1] + args[2]; break;
 		case 2: program[args[0]] = args[1] * args[2]; break;
 		case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal);if(!isFirst) part++; isFirst = false; break;
-		case 4: /*if(args[0]!=0)lastVal=args[0]; */return args[0];/*lastVal=args[0];*/  //break;
+		case 4: return args[0];
 		case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
 		case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
 		case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index b5bb81b6..ef389999 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -1,18 +1,19 @@
 package com.sbaars.adventofcode2019.intcode;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.stream.IntStream;
 
-public class IntcodeComputer extends Thread {
-	int[] program;
-	int instructionCounter;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class IntcodeComputer extends Thread implements DoesFileOperations {
+	final int[] program;
+	int instructionCounter = 0;
 	
 	public IntcodeComputer(int day) {
-		
+		this.program =  Arrays.stream(getFileAsString(new File(IntcodeComputer.class.getClassLoader().getResource("day7-3.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
 	}
-	
-	
-	
+
 	@Override
 	public void run() {
 		

From d34bd9d19910986ded9a527e37a9fd5af41254d5 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 20:17:44 +0100
Subject: [PATCH 024/120] Making the intcode computer wonderful

---
 .../sbaars/adventofcode2019/common/Day.java   |  4 --
 .../intcode/IntcodeComputer.java              | 50 ++++++++++++-------
 .../util/DoesFileOperations.java              |  4 ++
 3 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Day.java b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
index 080fb04f..0e077dda 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Day.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
@@ -12,8 +12,4 @@ public default void printParts() throws IOException {
 		System.out.println("Part 1 = "+part1());
 		System.out.println("Part 2 = "+part2());
 	}
-	
-	public default String readDay(int day) throws IOException {
-		return getResourceAsString("day"+day+".txt");
-	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index ef389999..8ad62999 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -1,22 +1,28 @@
 package com.sbaars.adventofcode2019.intcode;
 
-import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class IntcodeComputer extends Thread implements DoesFileOperations {
+public class IntcodeComputer implements DoesFileOperations {
 	final int[] program;
 	int instructionCounter = 0;
+	final Stack<Integer> input = new Stack<>();
 	
-	public IntcodeComputer(int day) {
-		this.program =  Arrays.stream(getFileAsString(new File(IntcodeComputer.class.getClassLoader().getResource("day7-3.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
+	public IntcodeComputer(int day, int...input) throws IOException {
+		this.program = Arrays.stream(readDay(day).split(",")).mapToInt(Integer::parseInt).toArray();
+		setInput(input);
 	}
 
-	@Override
-	public void run() {
-		
+	public int run() {
+		int result;
+		while((result = executeInstruction(program, program[instructionCounter])) == -1);
+		return result;
 	}
 	
 	private int executeProgram(int[] program, int c) throws IOException {
@@ -53,20 +59,30 @@ private int execute(int[] program, int[] method, int instruction) {
 		return executeInstruction(program, args, instruction);
 	}
 
+	private int readInput() {
+		if(input.size()>1)
+			return input.pop();
+		return input.peek();
+	}
+	
+	private boolean setInput(int...input) {
+		this.input.clear();
+		return this.input.addAll(Arrays.stream(input).boxed().collect(Collectors.toList()));
+	}
 	
 	private int executeInstruction(int[] program, int[] args, int instruction) {
+		instructionCounter+=nParams(instruction) + 1;
 		switch(instruction) {
-		case 1: program[args[0]] = args[1] + args[2]; break;
-		case 2: program[args[0]] = args[1] * args[2]; break;
-		case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal);if(!isFirst) part++; isFirst = false; break;
-		case 4: return args[0];
-		case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
-		case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
-		case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
-		case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
-		default: throw new IllegalStateException("Something went wrong!");
+			case 1: program[args[0]] = args[1] + args[2]; break;
+			case 2: program[args[0]] = args[1] * args[2]; break;
+			case 3: program[args[0]] = readInput(); break;
+			case 4: return args[0];
+			case 5: if(args[1] != 0) instructionCounter = args[0]; break;
+			case 6: if(args[1] == 0) instructionCounter = args[0]; break;
+			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
+			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
+			default: throw new IllegalStateException("Something went wrong!");
 		}
-		instructionCounter+=nParams(instruction) + 1;
 		return -1;
 	}
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java b/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
index d1e16d17..289ee81c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
+++ b/src/main/java/com/sbaars/adventofcode2019/util/DoesFileOperations.java
@@ -14,4 +14,8 @@ public default String getFileAsString(File file) throws IOException {
 	public default String getResourceAsString(String resource) throws IOException {
 		return getFileAsString(new File(DoesFileOperations.class.getClassLoader().getResource(resource).getFile()));
 	}
+	
+	public default String readDay(int day) throws IOException {
+		return getResourceAsString("day"+day+".txt");
+	}
 }
\ No newline at end of file

From 1a5466d60185a2de143827411745f9f977b135ec Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 20:44:37 +0100
Subject: [PATCH 025/120] Ported day 2 to the new intcode computer

---
 .../sbaars/adventofcode2019/days/Day2.java    | 26 +++---------
 .../intcode/IntcodeComputer.java              | 42 ++++++++++---------
 2 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index 4508b9a3..dc56d59a 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -1,9 +1,9 @@
 package com.sbaars.adventofcode2019.days;
 
 import java.io.IOException;
-import java.util.Arrays;
 
 import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class Day2 implements Day, DoesFileOperations {
@@ -14,10 +14,10 @@ public static void main(String[] args) throws IOException {
 	
 	@Override
 	public int part1() throws IOException {
-		return execute(12, 2);
+		return execute(12,2);
 	}
 	
-	@Override
+	@Override //3146
 	public int part2() throws IOException {
 		return bruteForceFindingNumber(19690720, 99);
 	}
@@ -34,22 +34,8 @@ private int bruteForceFindingNumber(int number, int bound) throws IOException {
 	}
 
 	private int execute(int x, int y) throws IOException {
-		int[] program = Arrays.stream(readDay(2).split(",")).mapToInt(Integer::parseInt).toArray();
-		program[1] = x;
-		program[2] = y;
-		for(int i = 0; executeInstruction(program, i, program[i]); i+=4);
-		return program[0];
+		IntcodeComputer computer = new IntcodeComputer(2, x, y);
+		computer.run();
+		return computer.firstElement();
 	}
-
-	private boolean executeInstruction(int[] program, int i, int instruction) {
-		switch(instruction) {
-			case 1: program[program[i+3]] = program[program[i+1]] + program[program[i+2]]; break;
-			case 2: program[program[i+3]] = program[program[i+1]] * program[program[i+2]]; break;
-			case 99: return false;
-			default: throw new IllegalStateException("Something went wrong!");
-		}
-		
-		return true;
-	}
-
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 8ad62999..f013669e 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -1,9 +1,9 @@
 package com.sbaars.adventofcode2019.intcode;
 
 import java.io.IOException;
+import java.util.ArrayDeque;
 import java.util.Arrays;
-import java.util.List;
-import java.util.Stack;
+import java.util.Deque;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
@@ -11,40 +11,38 @@
 
 public class IntcodeComputer implements DoesFileOperations {
 	final int[] program;
-	int instructionCounter = 0;
-	final Stack<Integer> input = new Stack<>();
+	private int instructionCounter = 0;
+	private final Deque<Integer> input = new ArrayDeque<>(2);
+	
+	private boolean done = false;
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
 		this.program = Arrays.stream(readDay(day).split(",")).mapToInt(Integer::parseInt).toArray();
 		setInput(input);
+		if(day == 2) {
+			program[1] = input[0];
+			program[2] = input[1];
+		}
 	}
-
+	
 	public int run() {
 		int result;
-		while((result = executeInstruction(program, program[instructionCounter])) == -1);
+		while((result = executeInstruction(program, program[instructionCounter])) == 0);
 		return result;
 	}
 	
-	private int executeProgram(int[] program, int c) throws IOException {
-		isFirst = c == 0;
-		int result;
-		while((result = executeInstruction(program, program[instructionCounter])) == -1);
-		return result;
+	public boolean isDone() {
+		return done;
 	}
 
 	private int executeInstruction(int[] program, int instruction) {
 		if(instruction>99) 
 			return parseComplexInstruction(program, instruction);
-		else if(instruction == 99) {
-			done = true;
-			return lastVal;
-		}
-		//throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
 		return execute(program, instruction);
 	}
 
 	private int execute(int[] program, int instruction) {
-		return execute(program, new int[NUM_MODES], instruction);
+		return execute(program, new int[3], instruction);
 	}
 
 	private int execute(int[] program, int[] method, int instruction) {
@@ -65,6 +63,10 @@ private int readInput() {
 		return input.peek();
 	}
 	
+	public int firstElement() {
+		return program[0];
+	}
+	
 	private boolean setInput(int...input) {
 		this.input.clear();
 		return this.input.addAll(Arrays.stream(input).boxed().collect(Collectors.toList()));
@@ -81,9 +83,10 @@ private int executeInstruction(int[] program, int[] args, int instruction) {
 			case 6: if(args[1] == 0) instructionCounter = args[0]; break;
 			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
 			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
+			case 99: return -1;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
-		return -1;
+		return 0;
 	}
 	
 	private int parseComplexInstruction(int[] program, int instruction) {
@@ -112,6 +115,7 @@ private int[] getInstructions(int instruction) {
 
 	private int nParams(int instruction) {
 		switch(instruction) {
+			case 99: return 0;
 			case 3: 
 			case 4: return 1;
 			case 5:
@@ -120,7 +124,7 @@ private int nParams(int instruction) {
 			case 2:
 			case 7:
 			case 8: return 3;
-			default: if(instruction>=99) return nParams(getOpCode(instruction));
+			default: if(instruction>99) return nParams(getOpCode(instruction));
 			else throw new IllegalStateException("Something went wrong! "+instruction);
 		}
 	}

From de00e141e097a78ffdcadb2bcbc28dade825ab03 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 21:26:49 +0100
Subject: [PATCH 026/120] Ported day 5 to the new intcode computer

---
 .../sbaars/adventofcode2019/days/Day5.java    | 102 +-----------------
 1 file changed, 4 insertions(+), 98 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index ead5ef56..22cb1358 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -1,118 +1,24 @@
 package com.sbaars.adventofcode2019.days;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class Day5 implements Day, DoesFileOperations {
-
-	private static final int NUM_MODES = 3;
-	private int instructionCounter = 0;
-	private int part;
-
+	
 	public static void main(String[] args) throws IOException {
 		new Day5().printParts();
 	}
 	
 	@Override
 	public int part1() throws IOException {
-		part = 1;
-		return execute();
+		return new IntcodeComputer(5, 1).run();
 	}
 	
 	@Override
 	public int part2() throws IOException {
-		part = 2;
-		instructionCounter = 0;
-		return execute();
-	}
-
-	private int execute() throws IOException {
-		int[] program = Arrays.stream(readDay(5).split(",")).mapToInt(Integer::parseInt).toArray();;
-		int result;
-		while((result = executeInstruction(program, program[instructionCounter])) == -1);
-		return result;
-	}
-
-	private int executeInstruction(int[] program, int instruction) {
-		if(instruction>99) 
-			return parseComplexInstruction(program, instruction);
-		else if(instruction == 99)
-			throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
-		return execute(program, instruction);
-	}
-	
-	private int execute(int[] program, int instruction) {
-		return execute(program, new int[NUM_MODES], instruction);
-	}
-
-	private int execute(int[] program, int[] method, int instruction) {
-		int nParams = nParams(instruction);
-		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
-		if(args.length>=2) {
-			if(method[2] == 0) args[1] = program[args[1]];
-			if(args.length>=3 && method[1] == 0) args[2] = program[args[2]];
-		}
-		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
-		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
-		return executeInstruction(program, args, instruction);
-	}
-	
-	private int executeInstruction(int[] program, int[] args, int instruction) {
-		switch(instruction) {
-			case 1: program[args[0]] = args[1] + args[2]; break;
-			case 2: program[args[0]] = args[1] * args[2]; break;
-			case 3: program[args[0]] = part == 1 ? 1 : 5; break;
-			case 4: if(args[0]!=0) return args[0]; break;
-			case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
-			case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
-			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
-			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
-			default: throw new IllegalStateException("Something went wrong!");
-		}
-		instructionCounter+=nParams(instruction) + 1;
-		return -1;
-	}
-	
-	private int parseComplexInstruction(int[] program, int instruction) {
-		int[] instructions = getInstructions(instruction);
-		int opcode = getOpCode(instructions);
-		return execute(program, instructions, 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 3: 
-			case 4: 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!");
-		}
+		return new IntcodeComputer(5, 5).run();
 	}
 }

From b1eeada1a59d1701ab11add0c861d578fd0d0647 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 7 Dec 2019 22:07:56 +0100
Subject: [PATCH 027/120] Ported day 7 to the new intcode computer

---
 .../sbaars/adventofcode2019/days/Day7.java    | 153 +++---------------
 .../intcode/IntcodeComputer.java              |  26 +--
 2 files changed, 31 insertions(+), 148 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index fb95f1e3..552368ab 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -1,30 +1,16 @@
 package com.sbaars.adventofcode2019.days;
 
-import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class Day7 implements Day, DoesFileOperations {
 
-	private static final int NUM_MODES = 3;
-	private int instructionCounter = 0;
-	private int part;
-	private int phase = 0;
-	private boolean isFirst = true;
-	private int[] startState;
-	private int lastVal = -1;
-	private boolean done = false;
-
-	public Day7() throws IOException {
-		startState = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
-	}
-
 	public static void main(String[] args) throws IOException {
 		new Day7().printParts();
 	}
@@ -33,18 +19,10 @@ public static void main(String[] args) throws IOException {
 	public int part1() throws IOException {
 		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
 		List<Integer> results = new ArrayList<>();
-		for(List<Integer> shuffle : permutations) {
-			lastVal = -1;
-			part = 0;
-			for(Integer i : shuffle) {
-				int[] program = new int[startState.length];
-				for(int j = 0; j<startState.length; j++) {
-					program[j] = startState[j];
-				}
-				phase = i;
-				lastVal = executeProgram(program, 0);
-				part++;
-			}
+		for(List<Integer> perm : permutations) {
+			int lastVal = 0;
+			for(Integer i : perm)
+				lastVal = new IntcodeComputer(7, i, lastVal).run();
 			results.add(lastVal);
 
 		}
@@ -55,25 +33,21 @@ public int part1() throws IOException {
 	public int part2() throws IOException {
 		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
 		List<Integer> results = new ArrayList<>();
-		for(List<Integer> shuffle : permutations) {
-			lastVal = 0;
-			part = 0;
-			int[][] programs = new int[shuffle.size()][startState.length];
-			for(int i = 0; i<programs.length; i++) {
-				for(int j = 0; j<startState.length; j++) {
-					programs[i][j] = startState[j];
+		perms: for(List<Integer> shuffle : permutations) {
+			IntcodeComputer[] computers = new IntcodeComputer[5];
+			for(int i = 0; i<computers.length; i++) computers[i] = new IntcodeComputer(7, shuffle.get(i));
+			int lastVal = 0;
+			while(true) {
+				for(IntcodeComputer c : computers) {
+					c.addInput(lastVal);
+					int thruster = lastVal;
+					lastVal = c.run();
+					if(lastVal == -1) {
+						results.add(thruster);
+						continue perms;
+					}
 				}
 			}
-			int[] instructionCounters = new int[5];
-			done = false;
-			while(!done) {
-				for(Integer i : shuffle) {
-					phase = i;
-					lastVal = executeProgram(programs[i-5], instructionCounters[i-5]);
-					instructionCounters[i-5] = instructionCounter+2;
-				}
-			}
-			results.add(lastVal);
 
 		}
 		return results.stream().mapToInt(e -> e).max().getAsInt();
@@ -97,95 +71,4 @@ public <E> List<List<E>> generatePerm(List<E> original) {
 		}
 		return returnValue;
 	}
-
-	private int executeProgram(int[] program, int c) throws IOException {
-		isFirst = c == 0;
-		instructionCounter = c;
-		// = Arrays.stream(getFileAsString(new File(Day1.class.getClassLoader().getResource("day7-3.txt").getFile())).split(",")).mapToInt(Integer::parseInt).toArray();
-		int result;
-		while((result = executeInstruction(program, program[instructionCounter])) == -1);
-		return result;
-	}
-
-	private int executeInstruction(int[] program, int instruction) {
-		if(instruction>99) 
-			return parseComplexInstruction(program, instruction);
-		else if(instruction == 99) {
-			done = true;
-			return lastVal;
-		}
-		//throw new IllegalStateException("Hit terminal code 99 before finding diagnostic code!");
-		return execute(program, instruction);
-	}
-
-	private int execute(int[] program, int instruction) {
-		return execute(program, new int[NUM_MODES], instruction);
-	}
-
-	private int execute(int[] program, int[] method, int instruction) {
-		int nParams = nParams(instruction);
-		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
-		if(args.length>=2) {
-			if(method[2] == 0) args[1] = program[args[1]];
-			if(args.length>=3 && method[1] == 0) args[2] = program[args[2]];
-		}
-		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
-		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
-		return executeInstruction(program, args, instruction);
-	}
-
-	private int executeInstruction(int[] program, int[] args, int instruction) {
-		switch(instruction) {
-		case 1: program[args[0]] = args[1] + args[2]; break;
-		case 2: program[args[0]] = args[1] * args[2]; break;
-		case 3: program[args[0]] = isFirst ? phase : (part == 0 ? 0 : lastVal);if(!isFirst) part++; isFirst = false; break;
-		case 4: return args[0];
-		case 5: if(args[1] != 0) { instructionCounter = args[0]; return -1; } break;
-		case 6: if(args[1] == 0) { instructionCounter = args[0]; return -1; } break;
-		case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
-		case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
-		default: throw new IllegalStateException("Something went wrong!");
-		}
-		instructionCounter+=nParams(instruction) + 1;
-		return -1;
-	}
-
-	private int parseComplexInstruction(int[] program, int instruction) {
-		int[] instructions = getInstructions(instruction);
-		int opcode = getOpCode(instructions);
-		return execute(program, instructions, 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 3: 
-		case 4: 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);
-		}
-	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index f013669e..9685f891 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -3,7 +3,7 @@
 import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Arrays;
-import java.util.Deque;
+import java.util.Queue;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
@@ -12,9 +12,8 @@
 public class IntcodeComputer implements DoesFileOperations {
 	final int[] program;
 	private int instructionCounter = 0;
-	private final Deque<Integer> input = new ArrayDeque<>(2);
-	
-	private boolean done = false;
+	private final Queue<Integer> input = new ArrayDeque<>(2);
+	private int lastInput;
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
 		this.program = Arrays.stream(readDay(day).split(",")).mapToInt(Integer::parseInt).toArray();
@@ -30,10 +29,6 @@ public int run() {
 		while((result = executeInstruction(program, program[instructionCounter])) == 0);
 		return result;
 	}
-	
-	public boolean isDone() {
-		return done;
-	}
 
 	private int executeInstruction(int[] program, int instruction) {
 		if(instruction>99) 
@@ -58,16 +53,21 @@ private int execute(int[] program, int[] method, int instruction) {
 	}
 
 	private int readInput() {
-		if(input.size()>1)
-			return input.pop();
-		return input.peek();
+		if(input.isEmpty())
+			return lastInput;
+		lastInput = input.poll();
+		return lastInput;
+	}
+	
+	public boolean addInput(int num) {
+		return input.add(num);
 	}
 	
 	public int firstElement() {
 		return program[0];
 	}
 	
-	private boolean setInput(int...input) {
+	public boolean setInput(int...input) {
 		this.input.clear();
 		return this.input.addAll(Arrays.stream(input).boxed().collect(Collectors.toList()));
 	}
@@ -115,7 +115,7 @@ private int[] getInstructions(int instruction) {
 
 	private int nParams(int instruction) {
 		switch(instruction) {
-			case 99: return 0;
+			case 99: return -1;
 			case 3: 
 			case 4: return 1;
 			case 5:

From 6e7f59982d814417bfc4424524dad55a59686a25 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 8 Dec 2019 06:31:39 +0100
Subject: [PATCH 028/120] Day 8

---
 .../sbaars/adventofcode2019/days/Day8.java    | 66 +++++++++++++++++++
 .../adventofcode2019/util/CountMap.java       | 52 +++++++++++++++
 src/main/resources/7-4.txt                    |  1 -
 src/main/resources/day7-2.txt                 |  1 -
 src/main/resources/day7-3.txt                 |  1 -
 src/main/resources/day8.txt                   |  1 +
 6 files changed, 119 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day8.java
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
 delete mode 100644 src/main/resources/7-4.txt
 delete mode 100644 src/main/resources/day7-2.txt
 delete mode 100644 src/main/resources/day7-3.txt
 create mode 100644 src/main/resources/day8.txt

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..00537dc8
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -0,0 +1,66 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.CountMap;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day8 implements Day, DoesFileOperations {
+
+	public static void main(String[] args) throws IOException {
+		new Day8().printParts();
+	}
+
+	@Override
+	public int part1() throws IOException {
+		char[] chars = readDay(8).toCharArray();
+		int[] pixels = IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
+		List<CountMap<Integer>> pixelCounts = new ArrayList<>();
+		for(int i = 0; i<pixels.length; i+=25*6) {
+			CountMap<Integer> cm = new CountMap<>();
+			for(int j = i; j<i+(25*6); j++) {
+				cm.increment(pixels[j]);
+			}
+			pixelCounts.add(cm);
+		}
+		System.out.println(pixelCounts.size());
+		CountMap<Integer> cm = pixelCounts.stream().reduce((e1, e2) -> e1.get(0) > e2.get(0) ? e2 : e1).get();
+		return cm.get(1) * cm.get(2);
+	}
+
+	@Override
+	public int part2() throws IOException {
+		char[] chars = readDay(8).toCharArray();
+		int[] pixels = IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
+		int[][] pixelArrays = splitArray(pixels, 100, 25*6);
+		int[] finalPixels = pixelArrays[0];
+		for(int i = 1; i<pixelArrays.length; i++) {
+			for(int j = 0; j<pixelArrays[i].length; j++) {
+				if(finalPixels[j] == 2) {
+					finalPixels[j] = pixelArrays[i][j];
+				}
+			}
+		}
+		System.out.println(Arrays.deepToString(pixelArrays));
+		System.out.println(Arrays.toString(finalPixels));
+		System.out.println(Arrays.deepToString(splitArray(finalPixels, 6, 25)));
+		return 0;
+	}
+	
+	int[][] splitArray(int[] arr, int x, int y){
+		int[][] pixelArrays = new int[x][y];
+		int cor = 0;
+		for(int i = 0; i<arr.length; i+=y) {
+			for(int j = i; j<i+y; j++) {
+				pixelArrays[cor][j-i] = arr[j];
+			}
+			cor++;
+		}
+		return pixelArrays;
+	}
+}
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..7b822c09
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
@@ -0,0 +1,52 @@
+package com.sbaars.adventofcode2019.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class CountMap<K> extends HashMap<K, Integer> {
+	/**
+	 * 
+	 */
+	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<K> amountPerCloneClassSize) {
+		amountPerCloneClassSize.entrySet().stream().forEach(e -> this.increment(e.getKey(), e.getValue()));
+	}
+}
diff --git a/src/main/resources/7-4.txt b/src/main/resources/7-4.txt
deleted file mode 100644
index 5ed292ba..00000000
--- a/src/main/resources/7-4.txt
+++ /dev/null
@@ -1 +0,0 @@
-3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
\ No newline at end of file
diff --git a/src/main/resources/day7-2.txt b/src/main/resources/day7-2.txt
deleted file mode 100644
index 993e2e04..00000000
--- a/src/main/resources/day7-2.txt
+++ /dev/null
@@ -1 +0,0 @@
-3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0
\ No newline at end of file
diff --git a/src/main/resources/day7-3.txt b/src/main/resources/day7-3.txt
deleted file mode 100644
index 4363e8ee..00000000
--- a/src/main/resources/day7-3.txt
+++ /dev/null
@@ -1 +0,0 @@
-3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
\ 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

From eb81b217df72da0b13d856fc05f69f2f2918b5f5 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 8 Dec 2019 06:36:55 +0100
Subject: [PATCH 029/120] Refactoring day 8

---
 .../sbaars/adventofcode2019/days/Day8.java    | 29 +++++++++++++------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 00537dc8..5f148b94 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -18,8 +18,19 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public int part1() throws IOException {
+		int[] pixels = readPixels();
+		List<CountMap<Integer>> pixelCounts = countPixels(pixels);
+		CountMap<Integer> 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();
 		int[] pixels = IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
+		return pixels;
+	}
+
+	private List<CountMap<Integer>> countPixels(int[] pixels) {
 		List<CountMap<Integer>> pixelCounts = new ArrayList<>();
 		for(int i = 0; i<pixels.length; i+=25*6) {
 			CountMap<Integer> cm = new CountMap<>();
@@ -28,16 +39,19 @@ public int part1() throws IOException {
 			}
 			pixelCounts.add(cm);
 		}
-		System.out.println(pixelCounts.size());
-		CountMap<Integer> cm = pixelCounts.stream().reduce((e1, e2) -> e1.get(0) > e2.get(0) ? e2 : e1).get();
-		return cm.get(1) * cm.get(2);
+		return pixelCounts;
 	}
 
 	@Override
 	public int part2() throws IOException {
-		char[] chars = readDay(8).toCharArray();
-		int[] pixels = IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
+		int[] pixels = readPixels();
 		int[][] pixelArrays = splitArray(pixels, 100, 25*6);
+		int[] finalPixels = determineFinalImage(pixelArrays);
+		System.out.println(Arrays.deepToString(splitArray(finalPixels, 6, 25)));
+		return 0;
+	}
+
+	private int[] determineFinalImage(int[][] pixelArrays) {
 		int[] finalPixels = pixelArrays[0];
 		for(int i = 1; i<pixelArrays.length; i++) {
 			for(int j = 0; j<pixelArrays[i].length; j++) {
@@ -46,10 +60,7 @@ public int part2() throws IOException {
 				}
 			}
 		}
-		System.out.println(Arrays.deepToString(pixelArrays));
-		System.out.println(Arrays.toString(finalPixels));
-		System.out.println(Arrays.deepToString(splitArray(finalPixels, 6, 25)));
-		return 0;
+		return finalPixels;
 	}
 	
 	int[][] splitArray(int[] arr, int x, int y){

From 12dc6f445d7489c7874646a0320f95997a7781eb Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 8 Dec 2019 17:51:07 +0100
Subject: [PATCH 030/120] Made the ascii art nicer

---
 .../com/sbaars/adventofcode2019/days/Day8.java    | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 5f148b94..5158422b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -4,6 +4,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
@@ -47,8 +48,8 @@ public int part2() throws IOException {
 		int[] pixels = readPixels();
 		int[][] pixelArrays = splitArray(pixels, 100, 25*6);
 		int[] finalPixels = determineFinalImage(pixelArrays);
-		System.out.println(Arrays.deepToString(splitArray(finalPixels, 6, 25)));
-		return 0;
+		Arrays.stream(splitArray(finalPixels, 6, 25)).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).forEach(System.out::println);
+		return 0; // Answer: FPUAR
 	}
 
 	private int[] determineFinalImage(int[][] pixelArrays) {
@@ -65,13 +66,9 @@ private int[] determineFinalImage(int[][] pixelArrays) {
 	
 	int[][] splitArray(int[] arr, int x, int y){
 		int[][] pixelArrays = new int[x][y];
-		int cor = 0;
-		for(int i = 0; i<arr.length; i+=y) {
-			for(int j = i; j<i+y; j++) {
-				pixelArrays[cor][j-i] = arr[j];
-			}
-			cor++;
-		}
+		for(int i = 0; i<arr.length; i+=y)
+			for(int j = i; j<i+y; j++)
+				pixelArrays[i/y][j-i] = arr[j];
 		return pixelArrays;
 	}
 }

From 6c09830931be63890ddd2a607de1906c115356f2 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 8 Dec 2019 17:59:11 +0100
Subject: [PATCH 031/120] Final refactoring and such for day 8

---
 .../sbaars/adventofcode2019/days/Day8.java    | 37 ++++++++++++-------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 5158422b..504045b5 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -12,6 +12,10 @@
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class Day8 implements Day, DoesFileOperations {
+	
+	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();
@@ -27,15 +31,14 @@ public int part1() throws IOException {
 
 	private int[] readPixels() throws IOException {
 		char[] chars = readDay(8).toCharArray();
-		int[] pixels = IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
-		return pixels;
+		return IntStream.range(0, chars.length).map(i -> Character.getNumericValue(chars[i])).toArray();
 	}
 
 	private List<CountMap<Integer>> countPixels(int[] pixels) {
 		List<CountMap<Integer>> pixelCounts = new ArrayList<>();
-		for(int i = 0; i<pixels.length; i+=25*6) {
+		for(int i = 0; i<pixels.length; i+=SIZE) {
 			CountMap<Integer> cm = new CountMap<>();
-			for(int j = i; j<i+(25*6); j++) {
+			for(int j = i; j<i+SIZE; j++) {
 				cm.increment(pixels[j]);
 			}
 			pixelCounts.add(cm);
@@ -43,24 +46,32 @@ private List<CountMap<Integer>> countPixels(int[] pixels) {
 		return pixelCounts;
 	}
 
+	
+	/*
+	   Answer:
+	   
+		████ ███  █  █  ██  ███  
+		â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ 
+		███  █  █ █  █ █  █ █  █ 
+		█    ███  █  █ ████ ███  
+		â–ˆ    â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ â–ˆ  
+		█    █     ██  █  █ █  █ 
+	 */
 	@Override
 	public int part2() throws IOException {
 		int[] pixels = readPixels();
-		int[][] pixelArrays = splitArray(pixels, 100, 25*6);
+		int[][] pixelArrays = splitArray(pixels, 100, SIZE);
 		int[] finalPixels = determineFinalImage(pixelArrays);
-		Arrays.stream(splitArray(finalPixels, 6, 25)).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).forEach(System.out::println);
-		return 0; // Answer: FPUAR
+		Arrays.stream(splitArray(finalPixels, DIM_X, DIM_Y)).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).forEach(System.out::println);
+		return 0;
 	}
 
 	private int[] determineFinalImage(int[][] pixelArrays) {
 		int[] finalPixels = pixelArrays[0];
-		for(int i = 1; i<pixelArrays.length; i++) {
-			for(int j = 0; j<pixelArrays[i].length; j++) {
-				if(finalPixels[j] == 2) {
+		for(int i = 1; i<pixelArrays.length; i++)
+			for(int j = 0; j<pixelArrays[i].length; j++)
+				if(finalPixels[j] == 2)
 					finalPixels[j] = pixelArrays[i][j];
-				}
-			}
-		}
 		return finalPixels;
 	}
 	

From 1a33582ba836ca83aba5eada3988c09d96c8b9bb Mon Sep 17 00:00:00 2001
From: Simon <8466614+SimonBaars@users.noreply.github.com>
Date: Sun, 8 Dec 2019 18:00:52 +0100
Subject: [PATCH 032/120] Update README.md

---
 README.md | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index e8336bc7..1c2ec76a 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,12 @@
 # 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)

From 0679b7edc5231e6b9b02d69c8c2d6fdb782b4fa2 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 9 Dec 2019 08:08:51 +0100
Subject: [PATCH 033/120] Day 9

---
 .../sbaars/adventofcode2019/days/Day2.java    |  2 +-
 .../sbaars/adventofcode2019/days/Day5.java    |  4 +-
 .../sbaars/adventofcode2019/days/Day7.java    |  4 +-
 .../sbaars/adventofcode2019/days/Day9.java    | 24 ++++++
 .../intcode/IntcodeComputer.java              | 76 +++++++++++--------
 src/main/resources/day10.txt                  |  1 +
 src/main/resources/day11.txt                  |  1 +
 src/main/resources/day9.txt                   |  1 +
 8 files changed, 78 insertions(+), 35 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day9.java
 create mode 100644 src/main/resources/day10.txt
 create mode 100644 src/main/resources/day11.txt
 create mode 100644 src/main/resources/day9.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index dc56d59a..b896fe01 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -36,6 +36,6 @@ private int bruteForceFindingNumber(int number, int bound) throws IOException {
 	private int execute(int x, int y) throws IOException {
 		IntcodeComputer computer = new IntcodeComputer(2, x, y);
 		computer.run();
-		return computer.firstElement();
+		return Math.toIntExact(computer.firstElement());
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 22cb1358..63089705 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -14,11 +14,11 @@ public static void main(String[] args) throws IOException {
 	
 	@Override
 	public int part1() throws IOException {
-		return new IntcodeComputer(5, 1).run();
+		return new IntcodeComputer(5, 1).runInt();
 	}
 	
 	@Override
 	public int part2() throws IOException {
-		return new IntcodeComputer(5, 5).run();
+		return new IntcodeComputer(5, 5).runInt();
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 552368ab..8d2f5f05 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -22,7 +22,7 @@ public int part1() throws IOException {
 		for(List<Integer> perm : permutations) {
 			int lastVal = 0;
 			for(Integer i : perm)
-				lastVal = new IntcodeComputer(7, i, lastVal).run();
+				lastVal = new IntcodeComputer(7, i, lastVal).runInt();
 			results.add(lastVal);
 
 		}
@@ -41,7 +41,7 @@ public int part2() throws IOException {
 				for(IntcodeComputer c : computers) {
 					c.addInput(lastVal);
 					int thruster = lastVal;
-					lastVal = c.run();
+					lastVal = c.runInt();
 					if(lastVal == -1) {
 						results.add(thruster);
 						continue perms;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
new file mode 100644
index 00000000..d4299d59
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
@@ -0,0 +1,24 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day9 implements Day, DoesFileOperations {
+
+	public static void main(String[] args) throws IOException {
+		new Day9().printParts();
+	}
+
+	@Override
+	public int part1() throws IOException {
+		return new IntcodeComputer(9, 1).runInt();
+	}
+	
+	@Override
+	public int part2() throws IOException {
+		return 0;
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 9685f891..b77104d0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -10,13 +10,14 @@
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class IntcodeComputer implements DoesFileOperations {
-	final int[] program;
+	final long[] program;
 	private int instructionCounter = 0;
 	private final Queue<Integer> input = new ArrayDeque<>(2);
 	private int lastInput;
+	private long relativeBase = 0;
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
-		this.program = Arrays.stream(readDay(day).split(",")).mapToInt(Integer::parseInt).toArray();
+		this.program = Arrays.stream(readDay(day).split(",")).mapToLong(Long::parseLong).toArray();
 		setInput(input);
 		if(day == 2) {
 			program[1] = input[0];
@@ -24,32 +25,42 @@ public IntcodeComputer(int day, int...input) throws IOException {
 		}
 	}
 	
-	public int run() {
-		int result;
-		while((result = executeInstruction(program, program[instructionCounter])) == 0);
+	public long run() {
+		long result;
+		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == 0);
 		return result;
 	}
 
-	private int executeInstruction(int[] program, int instruction) {
+	private long executeInstruction(int instruction) {
 		if(instruction>99) 
-			return parseComplexInstruction(program, instruction);
-		return execute(program, instruction);
+			return parseComplexInstruction(instruction);
+		return execute(instruction);
 	}
 
-	private int execute(int[] program, int instruction) {
-		return execute(program, new int[3], instruction);
+	private long execute(int instruction) {
+		return execute(new int[3], instruction);
 	}
 
-	private int execute(int[] program, int[] method, int instruction) {
+	private long execute(int[] method, int instruction) {
 		int nParams = nParams(instruction);
-		int[] args = IntStream.range(0, nParams).map(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
+		long[] args = IntStream.range(0, nParams).mapToLong(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
+		transformParam2(method, args);
+		transformDataForMode(method, instruction, args);
+		return executeInstruction(args, instruction);
+	}
+
+	private void transformParam2(int[] method, long[] args) {
 		if(args.length>=2) {
-			if(method[2] == 0) args[1] = program[args[1]];
-			if(args.length>=3 && method[1] == 0) args[2] = program[args[2]];
+			if(method[2] == 0 || method[2] == 2) args[1] = method[2] == 0 ? program[Math.toIntExact(args[1])] : program[Math.toIntExact(relativeBase+args[1])];
+			if(args.length>=3 && (method[1] == 0 || method[1] == 2)) args[2] = method[1] == 0 ? program[Math.toIntExact(args[2])] : program[Math.toIntExact(relativeBase+args[2])];
+		}
+	}
+
+	private void transformDataForMode(int[] method, int instruction, long[] args) {
+		if(instruction == 4 && (method[2] == 0 || method[2] == 2)) {
+			args[0] = method[2] == 0 ? program[Math.toIntExact(args[0])] : program[Math.toIntExact(relativeBase+args[0])];
 		}
-		if(instruction == 4 && method[2] == 0) args[0] = program[args[0]];
-		if((instruction == 5 || instruction == 6) && method[1] == 0) args[0] = program[args[0]];
-		return executeInstruction(program, args, instruction);
+		if((instruction == 5 || instruction == 6) && (method[1] == 0 || method[1] == 2)) args[0] = method[1] == 0 ? program[Math.toIntExact(args[0])] : program[Math.toIntExact(relativeBase+args[0])];
 	}
 
 	private int readInput() {
@@ -63,7 +74,7 @@ public boolean addInput(int num) {
 		return input.add(num);
 	}
 	
-	public int firstElement() {
+	public long firstElement() {
 		return program[0];
 	}
 	
@@ -72,28 +83,28 @@ public boolean setInput(int...input) {
 		return this.input.addAll(Arrays.stream(input).boxed().collect(Collectors.toList()));
 	}
 	
-	private int executeInstruction(int[] program, int[] args, int instruction) {
+	private long executeInstruction(long[] args, int instruction) {
 		instructionCounter+=nParams(instruction) + 1;
 		switch(instruction) {
-			case 1: program[args[0]] = args[1] + args[2]; break;
-			case 2: program[args[0]] = args[1] * args[2]; break;
-			case 3: program[args[0]] = readInput(); break;
+			case 1: program[Math.toIntExact(args[0])] = args[1] + args[2]; break;
+			case 2: program[Math.toIntExact(args[0])] = args[1] * args[2]; break;
+			case 3: program[Math.toIntExact(args[0])] = readInput(); break;
 			case 4: return args[0];
-			case 5: if(args[1] != 0) instructionCounter = args[0]; break;
-			case 6: if(args[1] == 0) instructionCounter = args[0]; break;
-			case 7: program[args[0]] = args[1] < args[2] ? 1 : 0; break;
-			case 8: program[args[0]] = args[1] == args[2] ? 1 : 0; break;
+			case 5: if(args[1] != 0) instructionCounter = Math.toIntExact(args[0]); break;
+			case 6: if(args[1] == 0) instructionCounter = Math.toIntExact(args[0]); break;
+			case 7: program[Math.toIntExact(args[0])] = args[1] < args[2] ? 1 : 0; break;
+			case 8: program[Math.toIntExact(args[0])] = args[1] == args[2] ? 1 : 0; break;
+			case 9: relativeBase += Math.toIntExact(args[0]); break;
 			case 99: return -1;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
 		return 0;
 	}
 	
-	private int parseComplexInstruction(int[] program, int instruction) {
+	private long parseComplexInstruction(int instruction) {
 		int[] instructions = getInstructions(instruction);
 		int opcode = getOpCode(instructions);
-		return execute(program, instructions, opcode);
-
+		return execute(instructions, opcode);
 	}
 
 	private int getOpCode(int instruction) {
@@ -117,7 +128,8 @@ private int nParams(int instruction) {
 		switch(instruction) {
 			case 99: return -1;
 			case 3: 
-			case 4: return 1;
+			case 4: 
+			case 9: return 1;
 			case 5:
 			case 6: return 2;
 			case 1: 
@@ -128,4 +140,8 @@ private int nParams(int instruction) {
 			else throw new IllegalStateException("Something went wrong! "+instruction);
 		}
 	}
+
+	public int runInt() {
+		return Math.toIntExact(run());
+	}
 }
diff --git a/src/main/resources/day10.txt b/src/main/resources/day10.txt
new file mode 100644
index 00000000..ad185663
--- /dev/null
+++ b/src/main/resources/day10.txt
@@ -0,0 +1 @@
+1102,34915192,34915192,7,4,7,99,0
\ 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..521db733
--- /dev/null
+++ b/src/main/resources/day11.txt
@@ -0,0 +1 @@
+109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99
\ 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

From 3135889005d34933965c6f745c2b02c4394bee30 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 9 Dec 2019 08:09:22 +0100
Subject: [PATCH 034/120] Day 9 part 2

---
 src/main/java/com/sbaars/adventofcode2019/days/Day9.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
index d4299d59..f346084f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
@@ -19,6 +19,6 @@ public int part1() throws IOException {
 	
 	@Override
 	public int part2() throws IOException {
-		return 0;
+		return new IntcodeComputer(9, 2).runInt();
 	}
 }

From f5c19b5cc3aa72c8d51ce0367e823a283d9d9df9 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 9 Dec 2019 12:03:39 +0100
Subject: [PATCH 035/120] Working on a refactoring for the intcodecomputer

---
 .../sbaars/adventofcode2019/days/Day6.java    |  3 +-
 .../intcode/IntcodeComputer.java              | 29 ++++++++++++-------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
index 87a900df..82231d94 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -11,8 +11,7 @@
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 import com.sbaars.adventofcode2019.util.ListMap;
 
-public class Day6 implements Day, DoesFileOperations
-{	
+public class Day6 implements Day, DoesFileOperations {	
 	
 	ListMap<String, String> orbits = new ListMap<>();
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index b77104d0..833e310e 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -15,6 +15,7 @@ public class IntcodeComputer implements DoesFileOperations {
 	private final Queue<Integer> input = new ArrayDeque<>(2);
 	private int lastInput;
 	private long relativeBase = 0;
+	private static final int[] DO_NOT_TRANSFORM_FINAL_ARGUMENT = {1, 2, 3, 7, 8};
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
 		this.program = Arrays.stream(readDay(day).split(",")).mapToLong(Long::parseLong).toArray();
@@ -43,13 +44,19 @@ private long execute(int instruction) {
 
 	private long execute(int[] method, int instruction) {
 		int nParams = nParams(instruction);
-		long[] args = IntStream.range(0, nParams).mapToLong(j -> j == 0 ? program[instructionCounter+nParams] : program[instructionCounter+j]).toArray();
-		transformParam2(method, args);
-		transformDataForMode(method, instruction, args);
+		long[] args = IntStream.range(0, nParams).mapToLong(j -> program[instructionCounter+j]).toArray();
+		//transformParam2(method, args);
+		//transformDataForMode(method, instruction, args);
+		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])]);
+	}
 
-	private void transformParam2(int[] method, long[] args) {
+	/*private void transformParam2(int[] method, long[] args) {
 		if(args.length>=2) {
 			if(method[2] == 0 || method[2] == 2) args[1] = method[2] == 0 ? program[Math.toIntExact(args[1])] : program[Math.toIntExact(relativeBase+args[1])];
 			if(args.length>=3 && (method[1] == 0 || method[1] == 2)) args[2] = method[1] == 0 ? program[Math.toIntExact(args[2])] : program[Math.toIntExact(relativeBase+args[2])];
@@ -61,7 +68,7 @@ private void transformDataForMode(int[] method, int instruction, long[] args) {
 			args[0] = method[2] == 0 ? program[Math.toIntExact(args[0])] : program[Math.toIntExact(relativeBase+args[0])];
 		}
 		if((instruction == 5 || instruction == 6) && (method[1] == 0 || method[1] == 2)) args[0] = method[1] == 0 ? program[Math.toIntExact(args[0])] : program[Math.toIntExact(relativeBase+args[0])];
-	}
+	}*/
 
 	private int readInput() {
 		if(input.isEmpty())
@@ -86,14 +93,14 @@ public boolean setInput(int...input) {
 	private long executeInstruction(long[] args, int instruction) {
 		instructionCounter+=nParams(instruction) + 1;
 		switch(instruction) {
-			case 1: program[Math.toIntExact(args[0])] = args[1] + args[2]; break;
-			case 2: program[Math.toIntExact(args[0])] = args[1] * args[2]; break;
+			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[1] != 0) instructionCounter = Math.toIntExact(args[0]); break;
-			case 6: if(args[1] == 0) instructionCounter = Math.toIntExact(args[0]); break;
-			case 7: program[Math.toIntExact(args[0])] = args[1] < args[2] ? 1 : 0; break;
-			case 8: program[Math.toIntExact(args[0])] = args[1] == args[2] ? 1 : 0; break;
+			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 -1;
 			default: throw new IllegalStateException("Something went wrong!");

From 0a0a79f4253ec6d768a43723a285866c9f503e7c Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 07:33:18 +0100
Subject: [PATCH 036/120] Day 10 part 1

---
 .../sbaars/adventofcode2019/days/Day10.java   | 92 +++++++++++++++++++
 src/main/resources/day10.txt                  | 40 +++++++-
 src/main/resources/day11.txt                  | 11 ++-
 src/main/resources/day12.txt                  | 10 ++
 4 files changed, 151 insertions(+), 2 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day10.java
 create mode 100644 src/main/resources/day12.txt

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..5df59c1d
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -0,0 +1,92 @@
+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.util.DoesFileOperations;
+
+public class Day10 implements Day, DoesFileOperations {
+
+	public static void main(String[] args) throws IOException {
+		new Day10().printParts();
+	}
+
+	@Override
+	public int part1() throws IOException {
+		String[] mapString = Arrays.stream(readDay(10).split(System.lineSeparator())).toArray(String[]::new);
+		char[][] map = new char[mapString.length][mapString[0].length()];
+		List<Point> asteroids = new ArrayList<>();
+		for(int i = 0; i<mapString.length; i++) {
+			for(int j = 0; j<mapString[i].length(); j++) {
+				map[i][j] = mapString[i].charAt(j);
+				if(map[i][j] == '#') {
+					asteroids.add(new Point(i, j));
+				}
+			}
+		}
+		int[] nVisible = new int[asteroids.size()];
+		for(int i = 0; i<nVisible.length; i++) {
+			nVisible[i] = countNVisible(asteroids, asteroids.get(i), new Point(mapString.length, mapString[0].length()));
+		}
+//		nVisible[0] = countNVisible(asteroids, new Point(7,4), new Point(mapString.length, mapString[0].length()));
+		return Arrays.stream(nVisible).max().getAsInt();
+	}
+	
+	private int countNVisible(List<Point> asteroids, Point asteroid, Point mapSize) {
+		//System.out.println("Count visible "+asteroid);
+		List<Point> visible = new ArrayList<>(asteroids);
+		for(int i = 0; i<visible.size(); i++) {
+			if(visible.get(i).equals(asteroid)){
+				continue;
+			}
+			Point rel = new Point(visible.get(i).x - asteroid.x, visible.get(i).y - asteroid.y);
+			int max = Math.max(Math.abs(rel.x)+1, Math.abs(rel.y)+1);
+			
+			if(visible.get(i).equals(new Point(4,4))) {
+				System.out.println("Hi");
+			}
+			
+			Point step = new Point(rel.x, rel.y);
+			for(int j = 2; j<=max; j++) {
+				if(addRel(rel.x) % j == 0 && addRel(rel.y) % j == 0) {
+					step = new Point(addRel(rel.x) / j, addRel(rel.y) / j);
+				}
+			}
+			Point rem = new Point(visible.get(i).x + step.x, visible.get(i).y+step.y);
+			
+			if(visible.get(i).equals(new Point(4,4))) {
+				System.out.println("Hi");
+			}
+			
+			while(rem.x<=mapSize.x && rem.y<=mapSize.y && rem.x>=0 && rem.y>=0) {
+				int index = visible.indexOf(rem);
+				if(index!=-1) {
+					visible.remove(index);
+					if(index<i)
+						i--;
+				}
+				rem = new Point(rem.x + step.x, rem.y+step.y);
+				
+			}
+		}
+		if(visible.size() == 37) System.out.println(asteroid);
+		return visible.size();
+	}
+
+	private int addRel(int x) {
+		if(x<0)
+			return x-1;
+		else if (x == 0)
+			return x;
+		return x+1;
+	}
+	
+	@Override
+	public int part2() throws IOException {
+		return 0;
+	}
+}
diff --git a/src/main/resources/day10.txt b/src/main/resources/day10.txt
index ad185663..110bc35d 100644
--- a/src/main/resources/day10.txt
+++ b/src/main/resources/day10.txt
@@ -1 +1,39 @@
-1102,34915192,34915192,7,4,7,99,0
\ No newline at end of file
+.............#..#.#......##........#..#
+.#...##....#........##.#......#......#.
+..#.#.#...#...#...##.#...#.............
+.....##.................#.....##..#.#.#
+......##...#.##......#..#.......#......
+......#.....#....#.#..#..##....#.......
+...................##.#..#.....#.....#.
+#.....#.##.....#...##....#####....#.#..
+..#.#..........#..##.......#.#...#....#
+...#.#..#...#......#..........###.#....
+##..##...#.#.......##....#.#..#...##...
+..........#.#....#.#.#......#.....#....
+....#.........#..#..##..#.##........#..
+........#......###..............#.#....
+...##.#...#.#.#......#........#........
+......##.#.....#.#.....#..#.....#.#....
+..#....#.###..#...##.#..##............#
+...##..#...#.##.#.#....#.#.....#...#..#
+......#............#.##..#..#....##....
+.#.#.......#..#...###...........#.#.##.
+........##........#.#...#.#......##....
+.#.#........#......#..........#....#...
+...............#...#........##..#.#....
+.#......#....#.......#..#......#.......
+.....#...#.#...#...#..###......#.##....
+.#...#..##................##.#.........
+..###...#.......#.##.#....#....#....#.#
+...#..#.......###.............##.#.....
+#..##....###.......##........#..#...#.#
+.#......#...#...#.##......#..#.........
+#...#.....#......#..##.............#...
+...###.........###.###.#.....###.#.#...
+#......#......#.#..#....#..#.....##.#..
+.##....#.....#...#.##..#.#..##.......#.
+..#........#.......##.##....#......#...
+##............#....#.#.....#...........
+........###.............##...#........#
+#.........#.....#..##.#.#.#..#....#....
+..............##.#.#.#...........#.....
\ No newline at end of file
diff --git a/src/main/resources/day11.txt b/src/main/resources/day11.txt
index 521db733..86503469 100644
--- a/src/main/resources/day11.txt
+++ b/src/main/resources/day11.txt
@@ -1 +1,10 @@
-109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99
\ No newline at end of file
+......#.#.
+#..#.#....
+..#######.
+.#.#.###..
+.#..#.....
+..#....#.#
+#..#....#.
+.##.#..###
+##...#..#.
+.#....####
\ 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..dc708abc
--- /dev/null
+++ b/src/main/resources/day12.txt
@@ -0,0 +1,10 @@
+#.#...#.#.
+.###....#.
+.#....#...
+##.#.#.#.#
+....#.#.#.
+.##..###.#
+..#...##..
+..##....##
+......#...
+.####.###.
\ No newline at end of file

From efd3eeeaac7644ce8c83ebe146d69ba5edc3eb22 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 08:34:35 +0100
Subject: [PATCH 037/120] Rewriting day 10

---
 .../sbaars/adventofcode2019/days/Day10.java   | 63 +++++++++++++------
 1 file changed, 44 insertions(+), 19 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index 5df59c1d..5a1442b6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -5,11 +5,16 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class Day10 implements Day, DoesFileOperations {
+	
+	private final List<Point> asteroids = new ArrayList<>();
+	private Point baseLocation;
 
 	public static void main(String[] args) throws IOException {
 		new Day10().printParts();
@@ -18,26 +23,22 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public int part1() throws IOException {
 		String[] mapString = Arrays.stream(readDay(10).split(System.lineSeparator())).toArray(String[]::new);
-		char[][] map = new char[mapString.length][mapString[0].length()];
-		List<Point> asteroids = new ArrayList<>();
 		for(int i = 0; i<mapString.length; i++) {
 			for(int j = 0; j<mapString[i].length(); j++) {
-				map[i][j] = mapString[i].charAt(j);
-				if(map[i][j] == '#') {
+				if(mapString[i].charAt(j) == '#') {
 					asteroids.add(new Point(i, j));
 				}
 			}
 		}
 		int[] nVisible = new int[asteroids.size()];
 		for(int i = 0; i<nVisible.length; i++) {
-			nVisible[i] = countNVisible(asteroids, asteroids.get(i), new Point(mapString.length, mapString[0].length()));
+			nVisible[i] = countNVisible(asteroids.get(i), new Point(mapString.length, mapString[0].length()));
 		}
-//		nVisible[0] = countNVisible(asteroids, new Point(7,4), new Point(mapString.length, mapString[0].length()));
+		baseLocation = asteroids.get(IntStream.range(0, nVisible.length).reduce((i, j) -> nVisible[i] > nVisible[j] ? i : j).getAsInt());
 		return Arrays.stream(nVisible).max().getAsInt();
 	}
 	
-	private int countNVisible(List<Point> asteroids, Point asteroid, Point mapSize) {
-		//System.out.println("Count visible "+asteroid);
+	private int countNVisible(Point asteroid, Point mapSize) {
 		List<Point> visible = new ArrayList<>(asteroids);
 		for(int i = 0; i<visible.size(); i++) {
 			if(visible.get(i).equals(asteroid)){
@@ -46,22 +47,14 @@ private int countNVisible(List<Point> asteroids, Point asteroid, Point mapSize)
 			Point rel = new Point(visible.get(i).x - asteroid.x, visible.get(i).y - asteroid.y);
 			int max = Math.max(Math.abs(rel.x)+1, Math.abs(rel.y)+1);
 			
-			if(visible.get(i).equals(new Point(4,4))) {
-				System.out.println("Hi");
-			}
-			
 			Point step = new Point(rel.x, rel.y);
 			for(int j = 2; j<=max; j++) {
 				if(addRel(rel.x) % j == 0 && addRel(rel.y) % j == 0) {
 					step = new Point(addRel(rel.x) / j, addRel(rel.y) / j);
 				}
 			}
-			Point rem = new Point(visible.get(i).x + step.x, visible.get(i).y+step.y);
-			
-			if(visible.get(i).equals(new Point(4,4))) {
-				System.out.println("Hi");
-			}
 			
+			Point rem = new Point(visible.get(i).x + step.x, visible.get(i).y+step.y);
 			while(rem.x<=mapSize.x && rem.y<=mapSize.y && rem.x>=0 && rem.y>=0) {
 				int index = visible.indexOf(rem);
 				if(index!=-1) {
@@ -70,10 +63,8 @@ private int countNVisible(List<Point> asteroids, Point asteroid, Point mapSize)
 						i--;
 				}
 				rem = new Point(rem.x + step.x, rem.y+step.y);
-				
 			}
 		}
-		if(visible.size() == 37) System.out.println(asteroid);
 		return visible.size();
 	}
 
@@ -87,6 +78,40 @@ else if (x == 0)
 	
 	@Override
 	public int part2() throws IOException {
+		List<Asteroid> asteroidList = asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(baseLocation, e), baseLocation.distance(e), e)).collect(Collectors.toList());
+		double currentRotation = -0.0000000000000000000000000001;
+		for(int destroyed = 0; destroyed<200; destroyed++) {
+			int nextRotation = ro
+		}
 		return 0;
 	}
+	
+	public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
+	{
+	    double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);
+	    theta += Math.PI/2.0;
+	    
+	    double angle = Math.toDegrees(theta);
+	    if (angle < 0) {
+	        angle += 360;
+	    }
+
+	    return angle;
+	}
+	
+	class Asteroid {
+		double rotation;
+		double distance;
+		Point position;
+		
+		
+		public Asteroid(double rotation, double distance, Point position) {
+			super();
+			this.rotation = rotation;
+			this.distance = distance;
+			this.position = position;
+		}
+		
+		
+	}
 }

From 17d885f9fdf7771b02c683ecaedf4c2639f33680 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 12:50:14 +0100
Subject: [PATCH 038/120] Rewrote day 10

---
 .../sbaars/adventofcode2019/days/Day10.java   | 77 ++++++++++---------
 src/main/resources/day13.txt                  |  5 ++
 2 files changed, 44 insertions(+), 38 deletions(-)
 create mode 100644 src/main/resources/day13.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index 5a1442b6..44299206 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -5,6 +5,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.OptionalDouble;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
@@ -26,46 +27,20 @@ public int part1() throws IOException {
 		for(int i = 0; i<mapString.length; i++) {
 			for(int j = 0; j<mapString[i].length(); j++) {
 				if(mapString[i].charAt(j) == '#') {
-					asteroids.add(new Point(i, j));
+					asteroids.add(new Point(j, i));
 				}
 			}
 		}
-		int[] nVisible = new int[asteroids.size()];
+		long[] nVisible = new long[asteroids.size()];
 		for(int i = 0; i<nVisible.length; i++) {
 			nVisible[i] = countNVisible(asteroids.get(i), new Point(mapString.length, mapString[0].length()));
 		}
 		baseLocation = asteroids.get(IntStream.range(0, nVisible.length).reduce((i, j) -> nVisible[i] > nVisible[j] ? i : j).getAsInt());
-		return Arrays.stream(nVisible).max().getAsInt();
+		return Math.toIntExact(Arrays.stream(nVisible).max().getAsLong());
 	}
 	
-	private int countNVisible(Point asteroid, Point mapSize) {
-		List<Point> visible = new ArrayList<>(asteroids);
-		for(int i = 0; i<visible.size(); i++) {
-			if(visible.get(i).equals(asteroid)){
-				continue;
-			}
-			Point rel = new Point(visible.get(i).x - asteroid.x, visible.get(i).y - asteroid.y);
-			int max = Math.max(Math.abs(rel.x)+1, Math.abs(rel.y)+1);
-			
-			Point step = new Point(rel.x, rel.y);
-			for(int j = 2; j<=max; j++) {
-				if(addRel(rel.x) % j == 0 && addRel(rel.y) % j == 0) {
-					step = new Point(addRel(rel.x) / j, addRel(rel.y) / j);
-				}
-			}
-			
-			Point rem = new Point(visible.get(i).x + step.x, visible.get(i).y+step.y);
-			while(rem.x<=mapSize.x && rem.y<=mapSize.y && rem.x>=0 && rem.y>=0) {
-				int index = visible.indexOf(rem);
-				if(index!=-1) {
-					visible.remove(index);
-					if(index<i)
-						i--;
-				}
-				rem = new Point(rem.x + step.x, rem.y+step.y);
-			}
-		}
-		return visible.size();
+	private long countNVisible(Point asteroid, Point mapSize) {
+		return asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(asteroid, e), asteroid.distance(e), e)).mapToDouble(e -> e.rotation).distinct().count();
 	}
 
 	private int addRel(int x) {
@@ -78,12 +53,25 @@ else if (x == 0)
 	
 	@Override
 	public int part2() throws IOException {
+		System.out.println("Base = "+baseLocation);
 		List<Asteroid> asteroidList = asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(baseLocation, e), baseLocation.distance(e), e)).collect(Collectors.toList());
-		double currentRotation = -0.0000000000000000000000000001;
-		for(int destroyed = 0; destroyed<200; destroyed++) {
-			int nextRotation = ro
+		asteroidList.remove(new Asteroid(0, 0, baseLocation));
+		Asteroid prevDestroyed = new Asteroid(Double.MIN_VALUE, 0, new Point(0,0));
+		for(int destroyed = 0; destroyed<250; 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();
+				Asteroid a = asteroidList.stream().filter(e -> e.rotation == nextRotation).reduce((a1, a2) -> a1.distance < a2.distance ? a1 : a2).get();
+				asteroidList.remove(a);
+				prevDestroyed = a;
+				System.out.println(destroyed+". BOOM "+a.position+" rot "+a.rotation+" dis "+a.distance);
+			} else {
+				prevDestroyed = new Asteroid(Double.MIN_VALUE, 0, new Point(0,0));
+				destroyed--;
+			}
 		}
-		return 0;
+		return prevDestroyed.position.x*100+prevDestroyed.position.y;
 	}
 	
 	public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
@@ -104,14 +92,27 @@ class Asteroid {
 		double distance;
 		Point position;
 		
-		
 		public Asteroid(double rotation, double distance, Point position) {
 			super();
 			this.rotation = rotation;
 			this.distance = distance;
 			this.position = position;
 		}
-		
-		
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((position == null) ? 0 : position.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (!(obj instanceof Asteroid))
+				return false;
+			Asteroid other = (Asteroid) obj;
+			return position.equals(other.position);
+		}
 	}
 }
diff --git a/src/main/resources/day13.txt b/src/main/resources/day13.txt
new file mode 100644
index 00000000..f59635f7
--- /dev/null
+++ b/src/main/resources/day13.txt
@@ -0,0 +1,5 @@
+.#....#####...#..
+##...##.#####..##
+##...#...#.#####.
+..#.....X...###..
+..#.#.....#....##
\ No newline at end of file

From 675997debd5d2e93b962734a694829284bff84d7 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 13:10:51 +0100
Subject: [PATCH 039/120] Finalize day 10

---
 .../sbaars/adventofcode2019/days/Day10.java   | 35 +++++--------------
 1 file changed, 9 insertions(+), 26 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index 44299206..f58bb14f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -2,7 +2,6 @@
 
 import java.awt.Point;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.OptionalDouble;
@@ -14,8 +13,13 @@
 
 public class Day10 implements Day, DoesFileOperations {
 	
-	private final List<Point> asteroids = new ArrayList<>();
+	private final List<Point> 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();
@@ -23,41 +27,21 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public int part1() throws IOException {
-		String[] mapString = Arrays.stream(readDay(10).split(System.lineSeparator())).toArray(String[]::new);
-		for(int i = 0; i<mapString.length; i++) {
-			for(int j = 0; j<mapString[i].length(); j++) {
-				if(mapString[i].charAt(j) == '#') {
-					asteroids.add(new Point(j, i));
-				}
-			}
-		}
 		long[] nVisible = new long[asteroids.size()];
-		for(int i = 0; i<nVisible.length; i++) {
-			nVisible[i] = countNVisible(asteroids.get(i), new Point(mapString.length, mapString[0].length()));
-		}
+		for(int i = 0; i<nVisible.length; i++) nVisible[i] = countNVisible(asteroids.get(i));
 		baseLocation = asteroids.get(IntStream.range(0, nVisible.length).reduce((i, j) -> nVisible[i] > nVisible[j] ? i : j).getAsInt());
 		return Math.toIntExact(Arrays.stream(nVisible).max().getAsLong());
 	}
 	
-	private long countNVisible(Point asteroid, Point mapSize) {
+	private long countNVisible(Point asteroid) {
 		return asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(asteroid, e), asteroid.distance(e), e)).mapToDouble(e -> e.rotation).distinct().count();
 	}
-
-	private int addRel(int x) {
-		if(x<0)
-			return x-1;
-		else if (x == 0)
-			return x;
-		return x+1;
-	}
 	
 	@Override
 	public int part2() throws IOException {
-		System.out.println("Base = "+baseLocation);
 		List<Asteroid> asteroidList = asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(baseLocation, e), baseLocation.distance(e), e)).collect(Collectors.toList());
-		asteroidList.remove(new Asteroid(0, 0, baseLocation));
 		Asteroid prevDestroyed = new Asteroid(Double.MIN_VALUE, 0, new Point(0,0));
-		for(int destroyed = 0; destroyed<250; destroyed++) {
+		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()) {
@@ -65,7 +49,6 @@ public int part2() throws IOException {
 				Asteroid a = asteroidList.stream().filter(e -> e.rotation == nextRotation).reduce((a1, a2) -> a1.distance < a2.distance ? a1 : a2).get();
 				asteroidList.remove(a);
 				prevDestroyed = a;
-				System.out.println(destroyed+". BOOM "+a.position+" rot "+a.rotation+" dis "+a.distance);
 			} else {
 				prevDestroyed = new Asteroid(Double.MIN_VALUE, 0, new Point(0,0));
 				destroyed--;

From 52fb8fea8e1d4429651057c9ce4b7754398cb69d Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 13:29:22 +0100
Subject: [PATCH 040/120] Final refactoring

---
 .../sbaars/adventofcode2019/days/Day10.java   | 50 ++++++++-----------
 1 file changed, 22 insertions(+), 28 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index f58bb14f..fd84a88b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -8,6 +8,8 @@
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
+import javax.swing.text.Position;
+
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
@@ -33,41 +35,24 @@ public int part1() throws IOException {
 		return Math.toIntExact(Arrays.stream(nVisible).max().getAsLong());
 	}
 	
-	private long countNVisible(Point asteroid) {
-		return asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(asteroid, e), asteroid.distance(e), e)).mapToDouble(e -> e.rotation).distinct().count();
-	}
-	
 	@Override
 	public int part2() throws IOException {
-		List<Asteroid> asteroidList = asteroids.stream().map(e -> new Asteroid(calcRotationAngleInDegrees(baseLocation, e), baseLocation.distance(e), e)).collect(Collectors.toList());
-		Asteroid prevDestroyed = new Asteroid(Double.MIN_VALUE, 0, new Point(0,0));
+		List<Asteroid> 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();
-				Asteroid a = asteroidList.stream().filter(e -> e.rotation == nextRotation).reduce((a1, a2) -> a1.distance < a2.distance ? a1 : a2).get();
-				asteroidList.remove(a);
-				prevDestroyed = a;
-			} else {
-				prevDestroyed = new Asteroid(Double.MIN_VALUE, 0, new Point(0,0));
-				destroyed--;
+				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;
 	}
 	
-	public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
-	{
-	    double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);
-	    theta += Math.PI/2.0;
-	    
-	    double angle = Math.toDegrees(theta);
-	    if (angle < 0) {
-	        angle += 360;
-	    }
-
-	    return angle;
+	private long countNVisible(Point asteroid) {
+		return asteroids.stream().map(e -> new Asteroid(asteroid, e)).mapToDouble(e -> e.rotation).distinct().count();
 	}
 	
 	class Asteroid {
@@ -75,11 +60,20 @@ class Asteroid {
 		double distance;
 		Point position;
 		
-		public Asteroid(double rotation, double distance, Point position) {
-			super();
-			this.rotation = rotation;
-			this.distance = distance;
-			this.position = 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;
 		}
 
 		@Override

From b25e30971fefde279682cb062091b410f0557aef Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 17:48:10 +0100
Subject: [PATCH 041/120] Making the intcode computer better

I wonder if tomorrow is another intcode assignment
---
 .../sbaars/adventofcode2019/days/Day10.java   |  2 --
 .../sbaars/adventofcode2019/days/Day2.java    |  2 +-
 .../intcode/IntcodeComputer.java              | 20 ++-----------------
 src/main/resources/day11.txt                  | 10 ----------
 src/main/resources/day12.txt                  | 10 ----------
 src/main/resources/day13.txt                  |  5 -----
 6 files changed, 3 insertions(+), 46 deletions(-)
 delete mode 100644 src/main/resources/day11.txt
 delete mode 100644 src/main/resources/day12.txt
 delete mode 100644 src/main/resources/day13.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index fd84a88b..5ded2040 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -8,8 +8,6 @@
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-import javax.swing.text.Position;
-
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index b896fe01..15799ce6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -17,7 +17,7 @@ public int part1() throws IOException {
 		return execute(12,2);
 	}
 	
-	@Override //3146
+	@Override 
 	public int part2() throws IOException {
 		return bruteForceFindingNumber(19690720, 99);
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 833e310e..3dfcee38 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -44,9 +44,7 @@ private long execute(int instruction) {
 
 	private long execute(int[] method, int instruction) {
 		int nParams = nParams(instruction);
-		long[] args = IntStream.range(0, nParams).mapToLong(j -> program[instructionCounter+j]).toArray();
-		//transformParam2(method, args);
-		//transformDataForMode(method, instruction, args);
+		long[] args = IntStream.range(1, nParams+1).mapToLong(j -> program[instructionCounter+j]).toArray();
 		transformParameters(method, args, instruction);
 		return executeInstruction(args, instruction);
 	}
@@ -55,21 +53,7 @@ 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])]);
 	}
-
-	/*private void transformParam2(int[] method, long[] args) {
-		if(args.length>=2) {
-			if(method[2] == 0 || method[2] == 2) args[1] = method[2] == 0 ? program[Math.toIntExact(args[1])] : program[Math.toIntExact(relativeBase+args[1])];
-			if(args.length>=3 && (method[1] == 0 || method[1] == 2)) args[2] = method[1] == 0 ? program[Math.toIntExact(args[2])] : program[Math.toIntExact(relativeBase+args[2])];
-		}
-	}
-
-	private void transformDataForMode(int[] method, int instruction, long[] args) {
-		if(instruction == 4 && (method[2] == 0 || method[2] == 2)) {
-			args[0] = method[2] == 0 ? program[Math.toIntExact(args[0])] : program[Math.toIntExact(relativeBase+args[0])];
-		}
-		if((instruction == 5 || instruction == 6) && (method[1] == 0 || method[1] == 2)) args[0] = method[1] == 0 ? program[Math.toIntExact(args[0])] : program[Math.toIntExact(relativeBase+args[0])];
-	}*/
-
+	
 	private int readInput() {
 		if(input.isEmpty())
 			return lastInput;
diff --git a/src/main/resources/day11.txt b/src/main/resources/day11.txt
deleted file mode 100644
index 86503469..00000000
--- a/src/main/resources/day11.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-......#.#.
-#..#.#....
-..#######.
-.#.#.###..
-.#..#.....
-..#....#.#
-#..#....#.
-.##.#..###
-##...#..#.
-.#....####
\ No newline at end of file
diff --git a/src/main/resources/day12.txt b/src/main/resources/day12.txt
deleted file mode 100644
index dc708abc..00000000
--- a/src/main/resources/day12.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-#.#...#.#.
-.###....#.
-.#....#...
-##.#.#.#.#
-....#.#.#.
-.##..###.#
-..#...##..
-..##....##
-......#...
-.####.###.
\ No newline at end of file
diff --git a/src/main/resources/day13.txt b/src/main/resources/day13.txt
deleted file mode 100644
index f59635f7..00000000
--- a/src/main/resources/day13.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-.#....#####...#..
-##...##.#####..##
-##...#...#.#####.
-..#.....X...###..
-..#.#.....#....##
\ No newline at end of file

From ab7cf52360c6501ef63505804d72d9dc61514125 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 18:41:11 +0100
Subject: [PATCH 042/120] Built a test for the intcode computer

---
 pom.xml                                       |  2 +-
 .../sbaars/adventofcode2019/days/Day9.java    |  4 +--
 .../sbaars/adventofcode2019/IntcodeTest.java  | 33 +++++++++++++++++++
 3 files changed, 36 insertions(+), 3 deletions(-)
 create mode 100644 src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java

diff --git a/pom.xml b/pom.xml
index 07702b4e..2c0cbecb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>3.8.1</version>
+      <version>3.8.2</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
index f346084f..a024bf01 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
@@ -13,8 +13,8 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException {
-		return new IntcodeComputer(9, 1).runInt();
+	public int part1() throws IOException { // Just append a 2 to the number ;-)
+		return Math.toIntExact(new IntcodeComputer(9, 1).run()-2000000000L);
 	}
 	
 	@Override
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..5afbaca7
--- /dev/null
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -0,0 +1,33 @@
+package com.sbaars.adventofcode2019;
+
+import java.io.IOException;
+
+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(new Day2().part1(), 8017076);
+		Assert.assertEquals(new Day2().part2(), 3146);
+	}
+	
+	public void testDay5() throws IOException {
+		Assert.assertEquals(new Day5().part1(), 11049715);
+		Assert.assertEquals(new Day5().part2(), 2140710);
+	}
+	
+	public void testDay7() throws IOException {
+		Assert.assertEquals(new Day7().part1(), 116680);
+		Assert.assertEquals(new Day7().part2(), 89603079);
+	}
+	
+	public void testDay9() throws IOException {
+		Assert.assertEquals(new Day9().part1(), 518058886);
+		Assert.assertEquals(new Day9().part2(), 44292);
+	}
+}

From 83a01d42c7d7a935cb22f24bdacda076ee223830 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 19:46:10 +0100
Subject: [PATCH 043/120] Intcode Computer: Flipping Arguments

---
 .../com/sbaars/adventofcode2019/intcode/IntcodeComputer.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 3dfcee38..602d7aa4 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -95,7 +95,7 @@ private long executeInstruction(long[] args, int instruction) {
 	private long parseComplexInstruction(int instruction) {
 		int[] instructions = getInstructions(instruction);
 		int opcode = getOpCode(instructions);
-		return execute(instructions, opcode);
+		return execute(new int[] {instructions[2], instructions[1], instructions[0]}, opcode);
 	}
 
 	private int getOpCode(int instruction) {

From 73c22bf56b7a3c8912ad36c182b77da73c578c5a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 19:48:42 +0100
Subject: [PATCH 044/120] Flip arguments for the intcode tests

---
 .../com/sbaars/adventofcode2019/IntcodeTest.java | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
index 5afbaca7..a7608e99 100644
--- a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -12,22 +12,22 @@
 
 public class IntcodeTest extends TestCase {
 	public void testDay2() throws IOException {
-		Assert.assertEquals(new Day2().part1(), 8017076);
-		Assert.assertEquals(new Day2().part2(), 3146);
+		Assert.assertEquals(8017076, new Day2().part1());
+		Assert.assertEquals(3146, new Day2().part2());
 	}
 	
 	public void testDay5() throws IOException {
-		Assert.assertEquals(new Day5().part1(), 11049715);
-		Assert.assertEquals(new Day5().part2(), 2140710);
+		Assert.assertEquals(11049715, new Day5().part1());
+		Assert.assertEquals(2140710, new Day5().part2());
 	}
 	
 	public void testDay7() throws IOException {
-		Assert.assertEquals(new Day7().part1(), 116680);
-		Assert.assertEquals(new Day7().part2(), 89603079);
+		Assert.assertEquals(116680, new Day7().part1());
+		Assert.assertEquals(89603079, new Day7().part2());
 	}
 	
 	public void testDay9() throws IOException {
-		Assert.assertEquals(new Day9().part1(), 518058886);
-		Assert.assertEquals(new Day9().part2(), 44292);
+		Assert.assertEquals(518058886, new Day9().part1());
+		Assert.assertEquals(44292, new Day9().part2());
 	}
 }

From 4c98a4e39d38aefa85890110c17201d40e03ad85 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 10 Dec 2019 20:44:49 +0100
Subject: [PATCH 045/120] Finish up intcode computer refactoring

---
 .classpath                                    |  5 +-
 pom.xml                                       | 47 +++++++++++--------
 .../sbaars/adventofcode2019/days/Day9.java    |  4 +-
 .../intcode/IntcodeComputer.java              |  7 ++-
 4 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/.classpath b/.classpath
index cd377e47..0c01b411 100644
--- a/.classpath
+++ b/.classpath
@@ -8,13 +8,14 @@
 	</classpathentry>
 	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
 		<attributes>
+			<attribute name="test" value="true"/>
 			<attribute name="optional" value="true"/>
 			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="test" value="true"/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-13-openjdk">
 		<attributes>
+			<attribute name="module" value="true"/>
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>
 	</classpathentry>
diff --git a/pom.xml b/pom.xml
index 2c0cbecb..d448fdd5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,25 +1,32 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
 
-  <groupId>com.sbaars</groupId>
-  <artifactId>adventofcode2019</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
-  <packaging>jar</packaging>
+	<groupId>com.sbaars</groupId>
+	<artifactId>adventofcode2019</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
 
-  <name>adventofcode2019</name>
-  <url>http://maven.apache.org</url>
+	<name>adventofcode2019</name>
+	<url>http://maven.apache.org</url>
 
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
 
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.2</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>3.8.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<version>1.18.8</version>
+			<scope>compile</scope>
+		</dependency>
+	</dependencies>
 </project>
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
index a024bf01..0b58467e 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
@@ -14,7 +14,9 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public int part1() throws IOException { // Just append a 2 to the number ;-)
-		return Math.toIntExact(new IntcodeComputer(9, 1).run()-2000000000L);
+		long res = new IntcodeComputer(9, 1).run();
+		System.out.println(res);
+		return Math.toIntExact(res-2000000000L);
 	}
 	
 	@Override
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 602d7aa4..1f641266 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -50,8 +50,11 @@ private long execute(int[] method, int 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])]);
+		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 int readInput() {

From dd3ae9f428f08c2b76734c34c0b2823e206481c0 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 06:37:22 +0100
Subject: [PATCH 046/120] Day 11 part 1

---
 .../sbaars/adventofcode2019/days/Day11.java   | 80 +++++++++++++++++++
 .../intcode/IntcodeComputer.java              | 13 ++-
 src/main/resources/day11.txt                  |  1 +
 3 files changed, 90 insertions(+), 4 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day11.java
 create mode 100644 src/main/resources/day11.txt

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..d7027319
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -0,0 +1,80 @@
+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.intcode.IntcodeComputer;
+import com.sbaars.adventofcode2019.util.DoesFileOperations;
+
+public class Day11 implements Day, DoesFileOperations {
+	
+	int face = 0;
+	Set<Point> paintedOnce = new HashSet<>();
+	Set<Point> whitePlaces = new HashSet<>();
+	
+	enum Direction { UP, RIGHT, DOWN, LEFT }
+	
+	Direction dir = Direction.UP;
+	
+	public void turn() {
+		int cur = dir.ordinal()+1;
+		if(cur == Direction.values().length)
+			cur = 0;
+		dir = Direction.values()[cur];
+	}
+
+	public static void main(String[] args) throws IOException {
+		new Day11().printParts();
+	}
+
+	@Override
+	public int part1() throws IOException {
+		IntcodeComputer c = new IntcodeComputer(11);
+		Point currentLocation = new Point(0,0);
+		
+		while(true) {
+			c.setInput(whitePlaces.contains(currentLocation) ? 1 : 0);
+			int paintColor = c.runInt();
+			if(paintColor == -2)
+				break;
+			int turn = c.runInt();
+			if(turn == -2)
+				break;
+			System.out.println("Loc = "+currentLocation+"Paint = " + paintColor+ ", turn = "+turn+", is space white = "+whitePlaces.contains(currentLocation));
+			paintedOnce.add(currentLocation);
+			if(paintColor == 1) {
+				whitePlaces.add(currentLocation);
+			} else if(paintColor == 0) {
+				whitePlaces.remove(currentLocation);
+			}
+			
+			if(turn == 1) {
+				turn();
+			}
+			currentLocation = move(currentLocation, dir);
+		}
+		return paintedOnce.size();
+	}
+	
+	private Point move(Point currentLocation, Direction dir2) {
+		switch (dir2) {
+		case UP:
+			return new Point(currentLocation.x, currentLocation.y+1);
+		case DOWN:
+			return new Point(currentLocation.x, currentLocation.y-1);
+		case RIGHT:
+			return new Point(currentLocation.x+1, currentLocation.y);
+		case LEFT:
+			return new Point(currentLocation.x-1, currentLocation.y);
+		}
+		return null;
+	}
+
+	@Override
+	public int part2() throws IOException {
+		return 0;
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 1f641266..b4322d94 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -10,7 +10,7 @@
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public class IntcodeComputer implements DoesFileOperations {
-	final long[] program;
+	private long[] program;
 	private int instructionCounter = 0;
 	private final Queue<Integer> input = new ArrayDeque<>(2);
 	private int lastInput;
@@ -19,6 +19,7 @@ public class IntcodeComputer implements DoesFileOperations {
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
 		this.program = Arrays.stream(readDay(day).split(",")).mapToLong(Long::parseLong).toArray();
+		this.program = Arrays.copyOf(this.program, 10000);
 		setInput(input);
 		if(day == 2) {
 			program[1] = input[0];
@@ -28,7 +29,7 @@ public IntcodeComputer(int day, int...input) throws IOException {
 	
 	public long run() {
 		long result;
-		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == 0);
+		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == -1);
 		return result;
 	}
 
@@ -50,8 +51,12 @@ private long execute(int[] method, int instruction) {
 	}
 	
 	private void transformParameters(int[] method, long[] args, int instruction) {
+		try { 
 		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])]);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
 		if(Arrays.stream(DO_NOT_TRANSFORM_FINAL_ARGUMENT).anyMatch(j -> j==instruction) && method[args.length-1] == 2) {
 			args[args.length-1] += relativeBase;
 		}
@@ -89,10 +94,10 @@ private long executeInstruction(long[] args, int instruction) {
 			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 -1;
+			case 99: return -2;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
-		return 0;
+		return -1;
 	}
 	
 	private long parseComplexInstruction(int instruction) {
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

From 04d4cdb4c79d16847ae6e1f68664c03d44852cf3 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 07:06:10 +0100
Subject: [PATCH 047/120] Day 11 part 2

---
 .../sbaars/adventofcode2019/days/Day11.java   | 43 +++++++++----------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index d7027319..0738dd16 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -11,19 +11,13 @@
 
 public class Day11 implements Day, DoesFileOperations {
 	
-	int face = 0;
-	Set<Point> paintedOnce = new HashSet<>();
-	Set<Point> whitePlaces = new HashSet<>();
-	
 	enum Direction { UP, RIGHT, DOWN, LEFT }
 	
-	Direction dir = Direction.UP;
-	
-	public void turn() {
+	public Direction turn(Direction dir) {
 		int cur = dir.ordinal()+1;
 		if(cur == Direction.values().length)
 			cur = 0;
-		dir = Direction.values()[cur];
+		return Direction.values()[cur];
 	}
 
 	public static void main(String[] args) throws IOException {
@@ -32,9 +26,18 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public int part1() throws IOException {
+		return robotWalk(false).size();
+	}
+
+	private Set<Point> robotWalk(boolean startWhite) throws IOException {
 		IntcodeComputer c = new IntcodeComputer(11);
 		Point currentLocation = new Point(0,0);
-		
+		int steps = 0;
+		Direction dir = Direction.UP;
+		Set<Point> paintedOnce = new HashSet<>();
+		Set<Point> whitePlaces = new HashSet<>();
+		if(startWhite)
+			whitePlaces.add(currentLocation);
 		while(true) {
 			c.setInput(whitePlaces.contains(currentLocation) ? 1 : 0);
 			int paintColor = c.runInt();
@@ -43,7 +46,7 @@ public int part1() throws IOException {
 			int turn = c.runInt();
 			if(turn == -2)
 				break;
-			System.out.println("Loc = "+currentLocation+"Paint = " + paintColor+ ", turn = "+turn+", is space white = "+whitePlaces.contains(currentLocation));
+			System.out.println("Loc = "+currentLocation+", step = "+steps+", Paint = " + paintColor+ ", turn = "+turn+", is space white = "+whitePlaces.contains(currentLocation));
 			paintedOnce.add(currentLocation);
 			if(paintColor == 1) {
 				whitePlaces.add(currentLocation);
@@ -51,30 +54,26 @@ public int part1() throws IOException {
 				whitePlaces.remove(currentLocation);
 			}
 			
-			if(turn == 1) {
-				turn();
-			}
+			if(turn == 1) dir = turn(dir);
 			currentLocation = move(currentLocation, dir);
+			steps++;
 		}
-		return paintedOnce.size();
+		return paintedOnce;
 	}
 	
 	private Point move(Point currentLocation, Direction dir2) {
 		switch (dir2) {
-		case UP:
-			return new Point(currentLocation.x, currentLocation.y+1);
-		case DOWN:
-			return new Point(currentLocation.x, currentLocation.y-1);
-		case RIGHT:
-			return new Point(currentLocation.x+1, currentLocation.y);
-		case LEFT:
-			return new Point(currentLocation.x-1, currentLocation.y);
+			case UP: return new Point(currentLocation.x, currentLocation.y+1);
+			case DOWN: return new Point(currentLocation.x, currentLocation.y-1);
+			case RIGHT: return new Point(currentLocation.x+1, currentLocation.y);
+			case LEFT: return new Point(currentLocation.x-1, currentLocation.y);
 		}
 		return null;
 	}
 
 	@Override
 	public int part2() throws IOException {
+		robotWalk(true);
 		return 0;
 	}
 }

From 65154534e99ab3f5978c5964b686a9f2936ccd2e Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 07:42:42 +0100
Subject: [PATCH 048/120] The answer is not always an integer

---
 .../sbaars/adventofcode2019/common/Day.java   |  8 +++---
 .../sbaars/adventofcode2019/days/Day1.java    |  4 +--
 .../sbaars/adventofcode2019/days/Day10.java   |  6 ++---
 .../sbaars/adventofcode2019/days/Day11.java   | 26 +++++++++----------
 .../sbaars/adventofcode2019/days/Day2.java    |  8 +++---
 .../sbaars/adventofcode2019/days/Day3.java    |  4 +--
 .../sbaars/adventofcode2019/days/Day4.java    |  4 +--
 .../sbaars/adventofcode2019/days/Day5.java    |  8 +++---
 .../sbaars/adventofcode2019/days/Day6.java    |  4 +--
 .../sbaars/adventofcode2019/days/Day7.java    |  4 +--
 .../sbaars/adventofcode2019/days/Day8.java    |  4 +--
 .../sbaars/adventofcode2019/days/Day9.java    | 10 +++----
 .../com/sbaars/adventofcode2019/util/OCR.java |  5 ++++
 13 files changed, 49 insertions(+), 46 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/util/OCR.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Day.java b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
index 0e077dda..badd6819 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Day.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Day.java
@@ -5,11 +5,11 @@
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
 public interface Day extends DoesFileOperations {
-	public int part1() throws IOException;
-	public int part2() throws IOException;
+	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/days/Day1.java b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
index c639cd9b..2aede117 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day1.java
@@ -14,12 +14,12 @@ public static void main(String[] args) throws IOException
     }
 
     @Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		return createNumberStream().map(this::getFuel).sum();
 	}
 	
     @Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		return createNumberStream().map(this::getRequiredFuel).sum();
 	}
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index 5ded2040..19e9b6ce 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -26,15 +26,15 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		long[] nVisible = new long[asteroids.size()];
 		for(int i = 0; i<nVisible.length; i++) nVisible[i] = countNVisible(asteroids.get(i));
 		baseLocation = asteroids.get(IntStream.range(0, nVisible.length).reduce((i, j) -> nVisible[i] > nVisible[j] ? i : j).getAsInt());
-		return Math.toIntExact(Arrays.stream(nVisible).max().getAsLong());
+		return Arrays.stream(nVisible).max().getAsLong();
 	}
 	
 	@Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		List<Asteroid> asteroidList = asteroids.stream().map(e -> new Asteroid(baseLocation, e)).collect(Collectors.toList());
 		Asteroid prevDestroyed = new Asteroid();
 		for(int destroyed = 1; destroyed<200; destroyed++) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 0738dd16..1376f62d 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -13,10 +13,12 @@ public class Day11 implements Day, DoesFileOperations {
 	
 	enum Direction { UP, RIGHT, DOWN, LEFT }
 	
-	public Direction turn(Direction dir) {
-		int cur = dir.ordinal()+1;
+	public Direction turn(Direction dir, boolean right) {
+		int cur = dir.ordinal() + (right ? 1 : -1);
 		if(cur == Direction.values().length)
 			cur = 0;
+		else if(cur == -1)
+			cur = 3;
 		return Direction.values()[cur];
 	}
 
@@ -25,17 +27,17 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException {
-		return robotWalk(false).size();
+	public Object part1() throws IOException {
+		return robotWalk(false);
 	}
 
-	private Set<Point> robotWalk(boolean startWhite) throws IOException {
+	private Object robotWalk(boolean startWhite) throws IOException {
 		IntcodeComputer c = new IntcodeComputer(11);
 		Point currentLocation = new Point(0,0);
 		int steps = 0;
 		Direction dir = Direction.UP;
-		Set<Point> paintedOnce = new HashSet<>();
-		Set<Point> whitePlaces = new HashSet<>();
+		final Set<Point> paintedOnce = new HashSet<>();
+		final Set<Point> whitePlaces = new HashSet<>();
 		if(startWhite)
 			whitePlaces.add(currentLocation);
 		while(true) {
@@ -46,7 +48,6 @@ private Set<Point> robotWalk(boolean startWhite) throws IOException {
 			int turn = c.runInt();
 			if(turn == -2)
 				break;
-			System.out.println("Loc = "+currentLocation+", step = "+steps+", Paint = " + paintColor+ ", turn = "+turn+", is space white = "+whitePlaces.contains(currentLocation));
 			paintedOnce.add(currentLocation);
 			if(paintColor == 1) {
 				whitePlaces.add(currentLocation);
@@ -54,11 +55,11 @@ private Set<Point> robotWalk(boolean startWhite) throws IOException {
 				whitePlaces.remove(currentLocation);
 			}
 			
-			if(turn == 1) dir = turn(dir);
+			dir = turn(dir, turn == 1);
 			currentLocation = move(currentLocation, dir);
 			steps++;
 		}
-		return paintedOnce;
+		return startWhite ? "JELEFGHP" : paintedOnce.size();
 	}
 	
 	private Point move(Point currentLocation, Direction dir2) {
@@ -72,8 +73,7 @@ private Point move(Point currentLocation, Direction dir2) {
 	}
 
 	@Override
-	public int part2() throws IOException {
-		robotWalk(true);
-		return 0;
+	public Object part2() throws IOException {
+		return robotWalk(true);
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index 15799ce6..ee75b695 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -13,12 +13,12 @@ public static void main(String[] args) throws IOException {
 	}
 	
 	@Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		return execute(12,2);
 	}
 	
 	@Override 
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		return bruteForceFindingNumber(19690720, 99);
 	}
 
@@ -33,9 +33,9 @@ private int bruteForceFindingNumber(int number, int bound) throws IOException {
 		return -1;
 	}
 
-	private int execute(int x, int y) throws IOException {
+	private long execute(int x, int y) throws IOException {
 		IntcodeComputer computer = new IntcodeComputer(2, x, y);
 		computer.run();
-		return Math.toIntExact(computer.firstElement());
+		return computer.firstElement();
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index fe3d90f1..0a37f868 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -27,12 +27,12 @@ public static void main(String[] args) throws IOException
     }
 
 	@Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		return intersect.stream().mapToInt(e -> distance(e.point)).min().orElse(Integer.MAX_VALUE);
 	}
 	
 	@Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		return intersect.stream().mapToInt(e -> e.steps).min().orElse(Integer.MAX_VALUE);
 	}
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day4.java b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
index ce7ef287..5031388b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day4.java
@@ -14,12 +14,12 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		return checkPasswords(false);
 	}
 	
 	@Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		return checkPasswords(true);
 	}
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 63089705..2c140236 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -13,12 +13,12 @@ public static void main(String[] args) throws IOException {
 	}
 	
 	@Override
-	public int part1() throws IOException {
-		return new IntcodeComputer(5, 1).runInt();
+	public Object part1() throws IOException {
+		return new IntcodeComputer(5, 1).run();
 	}
 	
 	@Override
-	public int part2() throws IOException {
-		return new IntcodeComputer(5, 5).runInt();
+	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
index 82231d94..4c87c8f7 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -21,7 +21,7 @@ public static void main(String[] args) throws IOException
     }
 
     @Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
     	String[] nums = createOrbitArray();
     	for(String num : nums) {
     		String[] parts = num.split("\\)");
@@ -43,7 +43,7 @@ private void countOrbitsInList(ListMap<String, String> orbits, AtomicInteger o,
 	}
 	
     @Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		return findRoute("YOU", "SAN");
 	}
     
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 8d2f5f05..51130286 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -16,7 +16,7 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
 		List<Integer> results = new ArrayList<>();
 		for(List<Integer> perm : permutations) {
@@ -30,7 +30,7 @@ public int part1() throws IOException {
 	}
 
 	@Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
 		List<Integer> results = new ArrayList<>();
 		perms: for(List<Integer> shuffle : permutations) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 504045b5..6c3e8623 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -22,7 +22,7 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException {
+	public Object part1() throws IOException {
 		int[] pixels = readPixels();
 		List<CountMap<Integer>> pixelCounts = countPixels(pixels);
 		CountMap<Integer> cm = pixelCounts.stream().reduce((e1, e2) -> e1.get(0) > e2.get(0) ? e2 : e1).get();
@@ -58,7 +58,7 @@ private List<CountMap<Integer>> countPixels(int[] pixels) {
 		█    █     ██  █  █ █  █ 
 	 */
 	@Override
-	public int part2() throws IOException {
+	public Object part2() throws IOException {
 		int[] pixels = readPixels();
 		int[][] pixelArrays = splitArray(pixels, 100, SIZE);
 		int[] finalPixels = determineFinalImage(pixelArrays);
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
index 0b58467e..0f725020 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
@@ -13,14 +13,12 @@ public static void main(String[] args) throws IOException {
 	}
 
 	@Override
-	public int part1() throws IOException { // Just append a 2 to the number ;-)
-		long res = new IntcodeComputer(9, 1).run();
-		System.out.println(res);
-		return Math.toIntExact(res-2000000000L);
+	public Object part1() throws IOException { // Just append a 2 to the number ;-)
+		return new IntcodeComputer(9, 1).run();
 	}
 	
 	@Override
-	public int part2() throws IOException {
-		return new IntcodeComputer(9, 2).runInt();
+	public Object part2() throws IOException {
+		return new IntcodeComputer(9, 2).run();
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/OCR.java b/src/main/java/com/sbaars/adventofcode2019/util/OCR.java
new file mode 100644
index 00000000..3ca3d013
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/util/OCR.java
@@ -0,0 +1,5 @@
+package com.sbaars.adventofcode2019.util;
+
+public class OCR {
+
+}

From 930efa93325415695c6ef7391184456f478e258c Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 08:06:51 +0100
Subject: [PATCH 049/120] Implemented OCR for day 8

---
 .../sbaars/adventofcode2019/days/Day11.java   |  2 --
 .../sbaars/adventofcode2019/days/Day8.java    | 16 ++-------
 .../com/sbaars/adventofcode2019/util/OCR.java | 36 +++++++++++++++++++
 3 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 1376f62d..65428ce6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -34,7 +34,6 @@ public Object part1() throws IOException {
 	private Object robotWalk(boolean startWhite) throws IOException {
 		IntcodeComputer c = new IntcodeComputer(11);
 		Point currentLocation = new Point(0,0);
-		int steps = 0;
 		Direction dir = Direction.UP;
 		final Set<Point> paintedOnce = new HashSet<>();
 		final Set<Point> whitePlaces = new HashSet<>();
@@ -57,7 +56,6 @@ private Object robotWalk(boolean startWhite) throws IOException {
 			
 			dir = turn(dir, turn == 1);
 			currentLocation = move(currentLocation, dir);
-			steps++;
 		}
 		return startWhite ? "JELEFGHP" : paintedOnce.size();
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 6c3e8623..45c8647b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -10,6 +10,7 @@
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.CountMap;
 import com.sbaars.adventofcode2019.util.DoesFileOperations;
+import com.sbaars.adventofcode2019.util.OCR;
 
 public class Day8 implements Day, DoesFileOperations {
 	
@@ -46,24 +47,13 @@ private List<CountMap<Integer>> countPixels(int[] pixels) {
 		return pixelCounts;
 	}
 
-	
-	/*
-	   Answer:
-	   
-		████ ███  █  █  ██  ███  
-		â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ 
-		███  █  █ █  █ █  █ █  █ 
-		█    ███  █  █ ████ ███  
-		â–ˆ    â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ â–ˆ  
-		█    █     ██  █  █ █  █ 
-	 */
 	@Override
 	public Object part2() throws IOException {
 		int[] pixels = readPixels();
 		int[][] pixelArrays = splitArray(pixels, 100, SIZE);
 		int[] finalPixels = determineFinalImage(pixelArrays);
-		Arrays.stream(splitArray(finalPixels, DIM_X, DIM_Y)).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).forEach(System.out::println);
-		return 0;
+		String[] image = Arrays.stream(splitArray(finalPixels, DIM_X, DIM_Y)).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).toArray(String[]::new);
+		return new OCR(image).getString();
 	}
 
 	private int[] determineFinalImage(int[][] pixelArrays) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/OCR.java b/src/main/java/com/sbaars/adventofcode2019/util/OCR.java
index 3ca3d013..e5c89fe4 100644
--- a/src/main/java/com/sbaars/adventofcode2019/util/OCR.java
+++ b/src/main/java/com/sbaars/adventofcode2019/util/OCR.java
@@ -1,5 +1,41 @@
 package com.sbaars.adventofcode2019.util;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class OCR {
+	
+	List<String[]> characters = new ArrayList<>();
 
+	public OCR(String[] image) {
+		for(int i = 0; i<image[0].length(); i+=5) {
+			String[] character = new String[image.length];
+			for(int j = 0; j<character.length; j++) {
+				character[j] = image[j].substring(i,i+4);
+			}
+			characters.add(character);
+		}
+	}
+	
+	// I will expand this as more characters present themselves throughout these challenges.
+	public String getString() {
+		StringBuilder result = new StringBuilder();
+		for(String[] character : characters) {
+			if(character[0].equals("████"))
+				result.append('F');
+			else if(character[0].equals("███ ")) {
+				if(character[5].equals("â–ˆ   "))
+					result.append('P');
+				else if(character[5].equals("â–ˆ  â–ˆ")) {
+					result.append('R');
+				}
+			} else if (character[0].equals("â–ˆ  â–ˆ")) {
+				result.append('U');
+			} else if(character[0].equals(" ██ ")) {
+				result.append('A');
+			}
+		}
+		return result.toString();
+	}
+	
 }

From e5019d937aabee9b4f93aa0a13cd8f0a0a91733c Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 18:44:48 +0100
Subject: [PATCH 050/120] stuff

---
 .../sbaars/adventofcode2019/days/Day11.java   | 27 ++++++++++++-------
 .../sbaars/adventofcode2019/IntcodeTest.java  | 10 +++----
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 65428ce6..ced60c60 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -12,15 +12,6 @@
 public class Day11 implements Day, DoesFileOperations {
 	
 	enum Direction { UP, RIGHT, DOWN, LEFT }
-	
-	public Direction turn(Direction dir, boolean right) {
-		int cur = dir.ordinal() + (right ? 1 : -1);
-		if(cur == Direction.values().length)
-			cur = 0;
-		else if(cur == -1)
-			cur = 3;
-		return Direction.values()[cur];
-	}
 
 	public static void main(String[] args) throws IOException {
 		new Day11().printParts();
@@ -57,7 +48,23 @@ private Object robotWalk(boolean startWhite) throws IOException {
 			dir = turn(dir, turn == 1);
 			currentLocation = move(currentLocation, dir);
 		}
-		return startWhite ? "JELEFGHP" : paintedOnce.size();
+		return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
+	}
+	
+	private int constructImage(Set<Point> 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));
+		return 0;
+	}
+
+	public Direction turn(Direction dir, boolean right) {
+		int cur = dir.ordinal() + (right ? 1 : -1);
+		if(cur == Direction.values().length)
+			cur = 0;
+		else if(cur == -1)
+			cur = 3;
+		return Direction.values()[cur];
 	}
 	
 	private Point move(Point currentLocation, Direction dir2) {
diff --git a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
index a7608e99..04ad01b3 100644
--- a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -12,13 +12,13 @@
 
 public class IntcodeTest extends TestCase {
 	public void testDay2() throws IOException {
-		Assert.assertEquals(8017076, new Day2().part1());
+		Assert.assertEquals(8017076L, new Day2().part1());
 		Assert.assertEquals(3146, new Day2().part2());
 	}
 	
 	public void testDay5() throws IOException {
-		Assert.assertEquals(11049715, new Day5().part1());
-		Assert.assertEquals(2140710, new Day5().part2());
+		Assert.assertEquals(11049715L, new Day5().part1());
+		Assert.assertEquals(2140710L, new Day5().part2());
 	}
 	
 	public void testDay7() throws IOException {
@@ -27,7 +27,7 @@ public void testDay7() throws IOException {
 	}
 	
 	public void testDay9() throws IOException {
-		Assert.assertEquals(518058886, new Day9().part1());
-		Assert.assertEquals(44292, new Day9().part2());
+		Assert.assertEquals(2518058886L, new Day9().part1());
+		Assert.assertEquals(44292L, new Day9().part2());
 	}
 }

From 2f102b0dadbad92b8adac423470bfa8944457042 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 20:05:06 +0100
Subject: [PATCH 051/120] Fixed broken intcode programs

---
 src/main/java/com/sbaars/adventofcode2019/days/Day5.java  | 5 ++++-
 src/main/java/com/sbaars/adventofcode2019/days/Day7.java  | 2 +-
 .../sbaars/adventofcode2019/intcode/IntcodeComputer.java  | 8 ++------
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index 2c140236..b66cb9c2 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -14,7 +14,10 @@ public static void main(String[] args) throws IOException {
 	
 	@Override
 	public Object part1() throws IOException {
-		return new IntcodeComputer(5, 1).run();
+		long res;
+		IntcodeComputer intcodeComputer = new IntcodeComputer(5, 1);
+		while((res = intcodeComputer.run()) == 0);
+		return res;
 	}
 	
 	@Override
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 51130286..57cb5138 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -42,7 +42,7 @@ public Object part2() throws IOException {
 					c.addInput(lastVal);
 					int thruster = lastVal;
 					lastVal = c.runInt();
-					if(lastVal == -1) {
+					if(lastVal == -2) {
 						results.add(thruster);
 						continue perms;
 					}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index b4322d94..9523ec25 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -19,7 +19,7 @@ public class IntcodeComputer implements DoesFileOperations {
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
 		this.program = Arrays.stream(readDay(day).split(",")).mapToLong(Long::parseLong).toArray();
-		this.program = Arrays.copyOf(this.program, 10000);
+		this.program = Arrays.copyOf(this.program, 10000); // Quick hack to enlange memory, should be refactored.
 		setInput(input);
 		if(day == 2) {
 			program[1] = input[0];
@@ -50,13 +50,9 @@ private long execute(int[] method, int instruction) {
 		return executeInstruction(args, instruction);
 	}
 	
-	private void transformParameters(int[] method, long[] args, int instruction) {
-		try { 
+	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])]);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
 		if(Arrays.stream(DO_NOT_TRANSFORM_FINAL_ARGUMENT).anyMatch(j -> j==instruction) && method[args.length-1] == 2) {
 			args[args.length-1] += relativeBase;
 		}

From a979e4ddfe43397cf32fe209e18a870146a1ee65 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 20:13:27 +0100
Subject: [PATCH 052/120] Lots' a stuff

---
 .../adventofcode2019/{util => common}/OCR.java     |  2 +-
 .../adventofcode2019/common/ProcessesImages.java   | 10 ++++++++++
 .../com/sbaars/adventofcode2019/days/Day10.java    |  3 +--
 .../com/sbaars/adventofcode2019/days/Day11.java    |  9 +++++++--
 .../com/sbaars/adventofcode2019/days/Day2.java     |  3 +--
 .../com/sbaars/adventofcode2019/days/Day3.java     |  3 +--
 .../com/sbaars/adventofcode2019/days/Day5.java     |  3 +--
 .../com/sbaars/adventofcode2019/days/Day6.java     |  3 +--
 .../com/sbaars/adventofcode2019/days/Day7.java     |  3 +--
 .../com/sbaars/adventofcode2019/days/Day8.java     | 14 +++++---------
 .../com/sbaars/adventofcode2019/days/Day9.java     |  5 ++---
 11 files changed, 31 insertions(+), 27 deletions(-)
 rename src/main/java/com/sbaars/adventofcode2019/{util => common}/OCR.java (95%)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/util/OCR.java b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
similarity index 95%
rename from src/main/java/com/sbaars/adventofcode2019/util/OCR.java
rename to src/main/java/com/sbaars/adventofcode2019/common/OCR.java
index e5c89fe4..3628f1d1 100644
--- a/src/main/java/com/sbaars/adventofcode2019/util/OCR.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
@@ -1,4 +1,4 @@
-package com.sbaars.adventofcode2019.util;
+package com.sbaars.adventofcode2019.common;
 
 import java.util.ArrayList;
 import java.util.List;
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..edb7eadd
--- /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[] createAsciiArray(int[][] pixels) {
+		return Arrays.stream(pixels).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).toArray(String[]::new);
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index 19e9b6ce..712aa57d 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -9,9 +9,8 @@
 import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day10 implements Day, DoesFileOperations {
+public class Day10 implements Day {
 	
 	private final List<Point> asteroids;
 	private Point baseLocation;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index ced60c60..2528af6f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -7,9 +7,8 @@
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day11 implements Day, DoesFileOperations {
+public class Day11 implements Day {
 	
 	enum Direction { UP, RIGHT, DOWN, LEFT }
 
@@ -55,6 +54,12 @@ private int constructImage(Set<Point> 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();
+		int sizey = whitePlaces.stream().mapToInt(e -> e.y).max().getAsInt();
+		int[][] places = new int[sizex][sizey];
+		for(Point p : whitePlaces) {
+			places[p.x][p.y] = 1;
+		}
 		return 0;
 	}
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index ee75b695..2f17263c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -4,9 +4,8 @@
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day2 implements Day, DoesFileOperations {
+public class Day2 implements Day {
 
 	public static void main(String[] args) throws IOException {
 		new Day2().printParts();
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 0a37f868..3199f6dd 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -7,9 +7,8 @@
 import java.util.Set;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day3 implements Day, DoesFileOperations
+public class Day3 implements Day
 {	
 	private Set<Step> intersect;
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
index b66cb9c2..0e5b4006 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day5.java
@@ -4,9 +4,8 @@
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day5 implements Day, DoesFileOperations {
+public class Day5 implements Day {
 	
 	public static void main(String[] args) throws IOException {
 		new Day5().printParts();
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
index 4c87c8f7..50813c0e 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -8,10 +8,9 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 import com.sbaars.adventofcode2019.util.ListMap;
 
-public class Day6 implements Day, DoesFileOperations {	
+public class Day6 implements Day {	
 	
 	ListMap<String, String> orbits = new ListMap<>();
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 57cb5138..530975e3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -7,9 +7,8 @@
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day7 implements Day, DoesFileOperations {
+public class Day7 implements Day {
 
 	public static void main(String[] args) throws IOException {
 		new Day7().printParts();
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 45c8647b..bf593ba9 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -2,17 +2,15 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 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.OCR;
+import com.sbaars.adventofcode2019.common.ProcessesImages;
 import com.sbaars.adventofcode2019.util.CountMap;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
-import com.sbaars.adventofcode2019.util.OCR;
 
-public class Day8 implements Day, DoesFileOperations {
+public class Day8 implements Day, ProcessesImages {
 	
 	private static final int DIM_X = 6;
 	private static final int DIM_Y = 25;
@@ -49,11 +47,9 @@ private List<CountMap<Integer>> countPixels(int[] pixels) {
 
 	@Override
 	public Object part2() throws IOException {
-		int[] pixels = readPixels();
-		int[][] pixelArrays = splitArray(pixels, 100, SIZE);
+		int[][] pixelArrays = splitArray(readPixels(), 100, SIZE);
 		int[] finalPixels = determineFinalImage(pixelArrays);
-		String[] image = Arrays.stream(splitArray(finalPixels, DIM_X, DIM_Y)).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).toArray(String[]::new);
-		return new OCR(image).getString();
+		return new OCR(createAsciiArray(splitArray(finalPixels, DIM_X, DIM_Y))).getString();
 	}
 
 	private int[] determineFinalImage(int[][] pixelArrays) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
index 0f725020..55c3b31c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day9.java
@@ -4,16 +4,15 @@
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
-import com.sbaars.adventofcode2019.util.DoesFileOperations;
 
-public class Day9 implements Day, DoesFileOperations {
+public class Day9 implements Day {
 
 	public static void main(String[] args) throws IOException {
 		new Day9().printParts();
 	}
 
 	@Override
-	public Object part1() throws IOException { // Just append a 2 to the number ;-)
+	public Object part1() throws IOException {
 		return new IntcodeComputer(9, 1).run();
 	}
 	

From e87eb70ea26cfc290ace91e528b59cdaf02c9879 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 20:21:44 +0100
Subject: [PATCH 053/120] Main method to run all

---
 .../java/com/sbaars/adventofcode2019/Main.java  | 17 +++++++++++++++++
 .../com/sbaars/adventofcode2019/days/Day3.java  |  2 +-
 2 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/Main.java

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..df476862
--- /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<=11; 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/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 3199f6dd..55a094b6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -12,7 +12,7 @@ public class Day3 implements Day
 {	
 	private Set<Step> intersect;
 	
-	private Day3() throws IOException {
+	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<Step> walkedLocations = new HashSet<>();

From e55b5e66906de0d9445444208d3b886c79267300 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 21:03:39 +0100
Subject: [PATCH 054/120] JAVA 13 LETZZZ GOOOO

---
 .classpath                                    |  2 +-
 .settings/org.eclipse.jdt.core.prefs          | 13 ++--
 pom.xml                                       | 13 ++++
 .../sbaars/adventofcode2019/common/OCR.java   | 65 ++++++++++++++-----
 .../sbaars/adventofcode2019/days/Day11.java   | 24 +++----
 .../sbaars/adventofcode2019/days/Day8.java    |  2 +-
 6 files changed, 84 insertions(+), 35 deletions(-)

diff --git a/.classpath b/.classpath
index 0c01b411..b51d40f7 100644
--- a/.classpath
+++ b/.classpath
@@ -13,7 +13,7 @@
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-13-openjdk">
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
 		<attributes>
 			<attribute name="module" value="true"/>
 			<attribute name="maven.pomderived" value="true"/>
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/pom.xml b/pom.xml
index d448fdd5..9f19708b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,9 @@
 
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.release>8</maven.compiler.release>
+		<maven.compiler.target>13</maven.compiler.target>
+		<maven.compiler.source>13</maven.compiler.source>
 	</properties>
 
 	<dependencies>
@@ -29,4 +32,14 @@
 			<scope>compile</scope>
 		</dependency>
 	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<release>13</release>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
 </project>
diff --git a/src/main/java/com/sbaars/adventofcode2019/common/OCR.java b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
index 3628f1d1..470e7c50 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
@@ -3,6 +3,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+@SuppressWarnings("preview")
 public class OCR {
 	
 	List<String[]> characters = new ArrayList<>();
@@ -16,26 +17,58 @@ public OCR(String[] image) {
 			characters.add(character);
 		}
 	}
-	
-	// I will expand this as more characters present themselves throughout these challenges.
-	public String getString() {
+
+	@Override
+	public String toString() {
 		StringBuilder result = new StringBuilder();
 		for(String[] character : characters) {
-			if(character[0].equals("████"))
-				result.append('F');
-			else if(character[0].equals("███ ")) {
-				if(character[5].equals("â–ˆ   "))
-					result.append('P');
-				else if(character[5].equals("â–ˆ  â–ˆ")) {
-					result.append('R');
-				}
-			} else if (character[0].equals("â–ˆ  â–ˆ")) {
-				result.append('U');
-			} else if(character[0].equals(" ██ ")) {
-				result.append('A');
-			}
+			result.append(switch(character[0]) {
+				case "████" -> fullTop(character);
+				case "███ " -> threeTopLeft(character);
+				case "â–ˆ  â–ˆ" -> bothSides(character);
+				case " ██ " -> middleTwo(character);
+				case "  ██" -> 'J';
+				case "â–ˆ   " -> 'L';
+				default -> dontKnow();
+			});
 		}
 		return result.toString();
 	}
+
+	private char bothSides(String[] character) {
+		return switch(character[5]) {
+			case " ██ " -> 'U';
+			case "â–ˆ  â–ˆ" -> 'H';
+			default -> dontKnow();
+		};
+	}
+
+	private char middleTwo(String[] character) {
+		return switch(character[5]) {
+			case " ███" -> 'G';
+			case "â–ˆ  â–ˆ" -> 'A';
+			default -> dontKnow();
+		};
+	}
+
+	private char dontKnow() {
+		throw new IllegalArgumentException("I don't know your character yet!");
+	}
+	
+	private char fullTop(String[] character) {
+		return switch(character[5]) {
+			case "â–ˆ   " -> 'F';
+			case "████" -> 'E';
+			default -> dontKnow();
+		};
+	}
+
+	private char threeTopLeft(String[] character) {
+		return switch(character[5]) {
+			case "â–ˆ   " -> 'P';
+			case "â–ˆ  â–ˆ" -> 'R';
+			default -> dontKnow();
+		};
+	}
 	
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 2528af6f..1313cee5 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -2,13 +2,16 @@
 
 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.OCR;
+import com.sbaars.adventofcode2019.common.ProcessesImages;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
 
-public class Day11 implements Day {
+public class Day11 implements Day, ProcessesImages {
 	
 	enum Direction { UP, RIGHT, DOWN, LEFT }
 
@@ -50,17 +53,16 @@ private Object robotWalk(boolean startWhite) throws IOException {
 		return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
 	}
 	
-	private int constructImage(Set<Point> whitePlaces) {
+	private OCR constructImage(Set<Point> 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();
-		int sizey = whitePlaces.stream().mapToInt(e -> e.y).max().getAsInt();
-		int[][] places = new int[sizex][sizey];
-		for(Point p : whitePlaces) {
-			places[p.x][p.y] = 1;
-		}
-		return 0;
+		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 new OCR(createAsciiArray(places));
 	}
 
 	public Direction turn(Direction dir, boolean right) {
@@ -74,8 +76,8 @@ else if(cur == -1)
 	
 	private Point move(Point currentLocation, Direction dir2) {
 		switch (dir2) {
-			case UP: return new Point(currentLocation.x, currentLocation.y+1);
-			case DOWN: return new Point(currentLocation.x, currentLocation.y-1);
+			case UP: return new Point(currentLocation.x, currentLocation.y-1);
+			case DOWN: return new Point(currentLocation.x, currentLocation.y+1);
 			case RIGHT: return new Point(currentLocation.x+1, currentLocation.y);
 			case LEFT: return new Point(currentLocation.x-1, currentLocation.y);
 		}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index bf593ba9..d2995743 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -49,7 +49,7 @@ private List<CountMap<Integer>> countPixels(int[] pixels) {
 	public Object part2() throws IOException {
 		int[][] pixelArrays = splitArray(readPixels(), 100, SIZE);
 		int[] finalPixels = determineFinalImage(pixelArrays);
-		return new OCR(createAsciiArray(splitArray(finalPixels, DIM_X, DIM_Y))).getString();
+		return new OCR(createAsciiArray(splitArray(finalPixels, DIM_X, DIM_Y)));
 	}
 
 	private int[] determineFinalImage(int[][] pixelArrays) {

From c40cdd8b4d5685c054eeb6018809a365b046df43 Mon Sep 17 00:00:00 2001
From: Simon <8466614+SimonBaars@users.noreply.github.com>
Date: Wed, 11 Dec 2019 21:04:39 +0100
Subject: [PATCH 055/120] Update README.md

---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
index 1c2ec76a..e0516844 100644
--- a/README.md
+++ b/README.md
@@ -10,3 +10,6 @@ Days:
 - [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)

From cd41983b8568f01875948e0a7c92cafe9ea28346 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 11 Dec 2019 21:07:32 +0100
Subject: [PATCH 056/120] Day 12: I'm ready :)

---
 .../sbaars/adventofcode2019/days/Day11.java   |  1 -
 .../sbaars/adventofcode2019/days/Day12.java   | 22 +++++++++++++++++++
 src/main/resources/day12.txt                  |  0
 3 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day12.java
 create mode 100644 src/main/resources/day12.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 1313cee5..3b49d2a6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -2,7 +2,6 @@
 
 import java.awt.Point;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
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..57091c92
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -0,0 +1,22 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Day12 implements Day {
+
+	public static void main(String[] args) throws IOException {
+		new Day12().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		return 0;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		return 0;
+	}
+}
diff --git a/src/main/resources/day12.txt b/src/main/resources/day12.txt
new file mode 100644
index 00000000..e69de29b

From 3910423ff1fa1184ce126366fe4cabcae3926122 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 06:32:13 +0100
Subject: [PATCH 057/120] Day 12 Part 1

---
 .../sbaars/adventofcode2019/days/Day12.java   | 37 ++++++++++++++++++-
 src/main/resources/day12.txt                  |  4 ++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index 57091c92..615265d6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -1,20 +1,53 @@
 package com.sbaars.adventofcode2019.days;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 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[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
+	//int[][] moons = {{-1,0,2},{2,-10,-7},{4,-8,8},{3,5,-1}};
+	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 {
-		return 0;
+		for(int n = 0; n<1000; n++) {
+			for(int i = 0; i<moons.length; i++) {
+				for(int j = i+1; j<moons.length; j++) {
+					for(int dim = 0; dim<moons[0].length; dim++) {
+						int moon1 = moons[i][dim], moon2 = moons[j][dim];
+						if(moon1 < moon2) {
+							velocity[i][dim]++;
+							velocity[j][dim]--;
+						} else if(moon1 > moon2) {
+							velocity[i][dim]--;
+							velocity[j][dim]++;
+						}
+					}
+				}
+			}
+			//System.out.println("Res = "+Arrays.deepToString(velocity));
+			for(int i = 0; i<moons.length; i++) {
+				for(int j = 0; j<moons[0].length; j++) {
+					moons[i][j]+=velocity[i][j];
+				}
+			}
+			//System.out.println("Moons = "+Arrays.deepToString(moons));
+		}
+		int[] res = new int[moons.length];
+		for(int i = 0; i<res.length; i++) {
+			res[i] = Arrays.stream(moons[i]).map(Math::abs).sum() * Arrays.stream(velocity[i]).map(Math::abs).sum();
+		}
+		return Arrays.stream(res).sum();
 	}
-	
+
 	@Override
 	public Object part2() throws IOException {
 		return 0;
diff --git a/src/main/resources/day12.txt b/src/main/resources/day12.txt
index e69de29b..e637be38 100644
--- a/src/main/resources/day12.txt
+++ b/src/main/resources/day12.txt
@@ -0,0 +1,4 @@
+<x=-5, y=6, z=-11>
+<x=-8, y=-4, z=-2>
+<x=1, y=16, z=4>
+<x=11, y=11, z=-4>
\ No newline at end of file

From faf2b2bd109d5f2a80676bedee107a5323ba48e8 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 06:58:54 +0100
Subject: [PATCH 058/120] Day 12 part 2: Optimization problem :O

---
 .../sbaars/adventofcode2019/days/Day12.java   | 70 ++++++++++++++++++-
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index 615265d6..a9d65b98 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -1,13 +1,18 @@
 package com.sbaars.adventofcode2019.days;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 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[][] moons = {{-5,6,-11},{-8,-4,-2},{1,16,4},{11,11,-4}};
 	//int[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
 	//int[][] moons = {{-1,0,2},{2,-10,-7},{4,-8,8},{3,5,-1}};
 	int[][] velocity = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
@@ -50,6 +55,67 @@ public Object part1() throws IOException {
 
 	@Override
 	public Object part2() throws IOException {
-		return 0;
+		Set<Numbers> set = new HashSet<>();
+		long n;
+		for(n = 0; true; n++) {
+			for(int i = 0; i<moons.length; i++) {
+				for(int j = i+1; j<moons.length; j++) {
+					for(int dim = 0; dim<moons[0].length; dim++) {
+						int moon1 = moons[i][dim], moon2 = moons[j][dim];
+						if(moon1 < moon2) {
+							velocity[i][dim]++;
+							velocity[j][dim]--;
+						} else if(moon1 > moon2) {
+							velocity[i][dim]--;
+							velocity[j][dim]++;
+						}
+					}
+				}
+			}
+			//System.out.println("Res = "+Arrays.deepToString(velocity));
+			for(int i = 0; i<moons.length; i++) {
+				for(int j = 0; j<moons[0].length; j++) {
+					moons[i][j]+=velocity[i][j];
+				}
+			}
+			//System.out.println("Moons = "+Arrays.deepToString(moons));
+			List<Integer> stuff = new ArrayList<>();
+			stuff.addAll(Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
+			stuff.addAll(Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
+			if(!set.add(new Numbers(stuff.stream().mapToInt(e -> e).toArray()))){
+				break;
+			}
+		}
+		return n;
+	}
+	
+	class Numbers{
+		int[] numbers;
+		
+		public Numbers(int...nums) {
+			this.numbers=nums;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + Arrays.hashCode(numbers);
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Numbers other = (Numbers) obj;
+			if (!Arrays.equals(numbers, other.numbers))
+				return false;
+			return true;
+		}
 	}
 }

From adbb1e2cc4e7c101e9f417990f1fdb3b76c83e97 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 07:26:51 +0100
Subject: [PATCH 059/120] How to optimize

---
 .../sbaars/adventofcode2019/days/Day12.java   | 53 ++++++++++---------
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index a9d65b98..fb282afe 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -1,19 +1,16 @@
 package com.sbaars.adventofcode2019.days;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 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[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
+	//int[][] moons = {{-5,6,-11},{-8,-4,-2},{1,16,4},{11,11,-4}};
+	int[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
 	//int[][] moons = {{-1,0,2},{2,-10,-7},{4,-8,8},{3,5,-1}};
 	int[][] velocity = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
 
@@ -65,9 +62,13 @@ public Object part2() throws IOException {
 						if(moon1 < moon2) {
 							velocity[i][dim]++;
 							velocity[j][dim]--;
+							//moons[i][dim]++;
+							//moons[j][dim]--;
 						} else if(moon1 > moon2) {
 							velocity[i][dim]--;
 							velocity[j][dim]++;
+							//moons[j][dim]++;
+							//moons[i][dim]--;
 						}
 					}
 				}
@@ -79,43 +80,47 @@ public Object part2() throws IOException {
 				}
 			}
 			//System.out.println("Moons = "+Arrays.deepToString(moons));
-			List<Integer> stuff = new ArrayList<>();
-			stuff.addAll(Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
-			stuff.addAll(Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
-			if(!set.add(new Numbers(stuff.stream().mapToInt(e -> e).toArray()))){
+			//List<Integer> stuff = new ArrayList<>();
+			//stuff.addAll(Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
+			//stuff.addAll(Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
+			if(!set.add(new Numbers(new int[][][] {moons,velocity}))){
+				//System.out.println(Arrays.deepToString(new int[][][] {moons,velocity}));
 				break;
 			}
+			
+			if(n % 1000000 == 0) {
+				int minMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
+				int maxMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
+				int minVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
+				int maxVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
+				System.out.println(n+". Moon: "+minMoon+", "+maxMoon+", Vel: "+minVel+", "+maxVel);
+			}
 		}
 		return n;
 	}
 	
 	class Numbers{
-		int[] numbers;
+		int[][][] numbers;
 		
-		public Numbers(int...nums) {
+		public Numbers(int[][][] nums) {
 			this.numbers=nums;
 		}
 
 		@Override
 		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result + Arrays.hashCode(numbers);
-			return result;
+			return Arrays.deepHashCode(numbers);
 		}
 
 		@Override
 		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
-				return false;
-			if (getClass() != obj.getClass())
-				return false;
 			Numbers other = (Numbers) obj;
-			if (!Arrays.equals(numbers, other.numbers))
-				return false;
-			return true;
+			//System.out.println("Check deep equals "+toString()+" between "+other.toString());
+			return Arrays.deepEquals(numbers, other.numbers);
+		}
+
+		@Override
+		public String toString() {
+			return "Numbers [numbers=" + Arrays.deepToString(numbers) + "]";
 		}
 	}
 }

From 3f6be9f107e7b969488a1f8e1e37256fc2ecd23d Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 07:48:18 +0100
Subject: [PATCH 060/120] Use shorts instead of integer

---
 .../sbaars/adventofcode2019/days/Day12.java   | 51 ++++++++++++-------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index fb282afe..8fede31b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -9,10 +9,10 @@
 
 public class Day12 implements Day {
 
-	//int[][] moons = {{-5,6,-11},{-8,-4,-2},{1,16,4},{11,11,-4}};
-	int[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
+	short[][] moons = {{-5,6,-11},{-8,-4,-2},{1,16,4},{11,11,-4}};
+	//int[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
 	//int[][] moons = {{-1,0,2},{2,-10,-7},{4,-8,8},{3,5,-1}};
-	int[][] velocity = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
+	short[][] velocity = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
 
 	public static void main(String[] args) throws IOException {
 		new Day12().printParts();
@@ -45,7 +45,7 @@ public Object part1() throws IOException {
 		}
 		int[] res = new int[moons.length];
 		for(int i = 0; i<res.length; i++) {
-			res[i] = Arrays.stream(moons[i]).map(Math::abs).sum() * Arrays.stream(velocity[i]).map(Math::abs).sum();
+			//res[i] = Arrays.stream(moons[i]).map(Math::abs).sum() * Arrays.stream(velocity[i]).map(Math::abs).sum();
 		}
 		return Arrays.stream(res).sum();
 	}
@@ -62,13 +62,9 @@ public Object part2() throws IOException {
 						if(moon1 < moon2) {
 							velocity[i][dim]++;
 							velocity[j][dim]--;
-							//moons[i][dim]++;
-							//moons[j][dim]--;
 						} else if(moon1 > moon2) {
 							velocity[i][dim]--;
 							velocity[j][dim]++;
-							//moons[j][dim]++;
-							//moons[i][dim]--;
 						}
 					}
 				}
@@ -79,30 +75,46 @@ public Object part2() throws IOException {
 					moons[i][j]+=velocity[i][j];
 				}
 			}
+			
 			//System.out.println("Moons = "+Arrays.deepToString(moons));
-			//List<Integer> stuff = new ArrayList<>();
-			//stuff.addAll(Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
-			//stuff.addAll(Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
-			if(!set.add(new Numbers(new int[][][] {moons,velocity}))){
+//			List<Integer> stuff = new ArrayList<>();
+//			stuff.addAll(Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
+//			stuff.addAll(Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
+//			if(n == 65976L || n == 45167L) {
+//				System.out.println(Arrays.toString(stuff.toArray()));
+//			}
+//			
+//			if(!set2.add(stuff)) {
+//				System.out.println("Stuff is filled!");
+//			}
+			if(!set.add(new Numbers(new short[][][] {copy(moons),copy(velocity)}))){
 				//System.out.println(Arrays.deepToString(new int[][][] {moons,velocity}));
 				break;
 			}
 			
 			if(n % 1000000 == 0) {
-				int minMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
-				int maxMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
-				int minVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
-				int maxVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
-				System.out.println(n+". Moon: "+minMoon+", "+maxMoon+", Vel: "+minVel+", "+maxVel);
+				System.out.println(n);
+				//int minMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
+				//int maxMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
+				//int minVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
+				//int maxVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
+				//System.out.println(n+". Moon: "+minMoon+", "+maxMoon+", Vel: "+minVel+", "+maxVel);
 			}
 		}
 		return n;
 	}
 	
+	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;
+	}
+	
 	class Numbers{
-		int[][][] numbers;
+		short[][][] numbers;
 		
-		public Numbers(int[][][] nums) {
+		public Numbers(short[][][] nums) {
 			this.numbers=nums;
 		}
 
@@ -114,6 +126,7 @@ public int hashCode() {
 		@Override
 		public boolean equals(Object obj) {
 			Numbers other = (Numbers) obj;
+//			System.out.println(iter+", "+other.iter);
 			//System.out.println("Check deep equals "+toString()+" between "+other.toString());
 			return Arrays.deepEquals(numbers, other.numbers);
 		}

From 064e8460d774a16355e81b2decdb895c251aada4 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 08:22:38 +0100
Subject: [PATCH 061/120] Some trick to find cycles

---
 .../sbaars/adventofcode2019/days/Day12.java   | 51 +++++++++++++------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index 8fede31b..a14b3094 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -3,6 +3,7 @@
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import com.sbaars.adventofcode2019.common.Day;
@@ -52,9 +53,9 @@ public Object part1() throws IOException {
 
 	@Override
 	public Object part2() throws IOException {
-		Set<Numbers> set = new HashSet<>();
-		long n;
-		for(n = 0; true; n++) {
+		final List<Set<List<Short>>> sets = Arrays.asList(new HashSet<List<Short>>(), new HashSet<List<Short>>(), new HashSet<List<Short>>());
+		long[] res = new long[sets.size()];
+		for(long n = 0; true; n++) {
 			for(int i = 0; i<moons.length; i++) {
 				for(int j = i+1; j<moons.length; j++) {
 					for(int dim = 0; dim<moons[0].length; dim++) {
@@ -87,23 +88,41 @@ public Object part2() throws IOException {
 //			if(!set2.add(stuff)) {
 //				System.out.println("Stuff is filled!");
 //			}
-			if(!set.add(new Numbers(new short[][][] {copy(moons),copy(velocity)}))){
-				//System.out.println(Arrays.deepToString(new int[][][] {moons,velocity}));
-				break;
-			}
-			
-			if(n % 1000000 == 0) {
-				System.out.println(n);
-				//int minMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
-				//int maxMoon = Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
-				//int minVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).min().getAsInt();
-				//int maxVel = Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).max().getAsInt();
-				//System.out.println(n+". Moon: "+minMoon+", "+maxMoon+", Vel: "+minVel+", "+maxVel);
+			for(int i = 0; i<sets.size(); i++) {
+				if(res[i] == 0 && !sets.get(i).add(Arrays.asList(moons[0][i], moons[1][i], moons[2][i], moons[3][i],velocity[0][i], velocity[1][i], velocity[2][i], velocity[3][i]))){
+					res[i] = n;
+					if(Arrays.stream(res).noneMatch(x -> x == 0)) {
+						return lcm(res);
+					}
+				}
 			}
 		}
-		return n;
 	}
 	
+	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++)

From 9aea55bd309c9d57869046ced50c77ff5d2c853a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 08:29:42 +0100
Subject: [PATCH 062/120] Refactor

---
 .../sbaars/adventofcode2019/days/Day12.java   | 129 +++++-------------
 1 file changed, 37 insertions(+), 92 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index a14b3094..50a92bbf 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -2,18 +2,15 @@
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
 
 import com.sbaars.adventofcode2019.common.Day;
 
 public class Day12 implements Day {
 
-	short[][] moons = {{-5,6,-11},{-8,-4,-2},{1,16,4},{11,11,-4}};
-	//int[][] moons = {{-8,-10,0},{5,5,10},{2,-7,3},{9,-8,-3}};
-	//int[][] moons = {{-1,0,2},{2,-10,-7},{4,-8,8},{3,5,-1}};
-	short[][] velocity = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
+	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();
@@ -22,72 +19,24 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		for(int n = 0; n<1000; n++) {
-			for(int i = 0; i<moons.length; i++) {
-				for(int j = i+1; j<moons.length; j++) {
-					for(int dim = 0; dim<moons[0].length; dim++) {
-						int moon1 = moons[i][dim], moon2 = moons[j][dim];
-						if(moon1 < moon2) {
-							velocity[i][dim]++;
-							velocity[j][dim]--;
-						} else if(moon1 > moon2) {
-							velocity[i][dim]--;
-							velocity[j][dim]++;
-						}
-					}
-				}
-			}
-			//System.out.println("Res = "+Arrays.deepToString(velocity));
-			for(int i = 0; i<moons.length; i++) {
-				for(int j = 0; j<moons[0].length; j++) {
-					moons[i][j]+=velocity[i][j];
-				}
-			}
-			//System.out.println("Moons = "+Arrays.deepToString(moons));
+			determineVelocity();
+			moveMoonsUsingVelocity();
 		}
 		int[] res = new int[moons.length];
 		for(int i = 0; i<res.length; i++) {
-			//res[i] = Arrays.stream(moons[i]).map(Math::abs).sum() * Arrays.stream(velocity[i]).map(Math::abs).sum();
+			res[i] = Arrays.stream(moons[i]).map(Math::abs).sum() * Arrays.stream(velocity[i]).map(Math::abs).sum();
 		}
 		return Arrays.stream(res).sum();
 	}
 
 	@Override
 	public Object part2() throws IOException {
-		final List<Set<List<Short>>> sets = Arrays.asList(new HashSet<List<Short>>(), new HashSet<List<Short>>(), new HashSet<List<Short>>());
+		final var sets = Collections.nCopies(moons[0].length, new HashSet<>());
 		long[] res = new long[sets.size()];
 		for(long n = 0; true; n++) {
-			for(int i = 0; i<moons.length; i++) {
-				for(int j = i+1; j<moons.length; j++) {
-					for(int dim = 0; dim<moons[0].length; dim++) {
-						int moon1 = moons[i][dim], moon2 = moons[j][dim];
-						if(moon1 < moon2) {
-							velocity[i][dim]++;
-							velocity[j][dim]--;
-						} else if(moon1 > moon2) {
-							velocity[i][dim]--;
-							velocity[j][dim]++;
-						}
-					}
-				}
-			}
-			//System.out.println("Res = "+Arrays.deepToString(velocity));
-			for(int i = 0; i<moons.length; i++) {
-				for(int j = 0; j<moons[0].length; j++) {
-					moons[i][j]+=velocity[i][j];
-				}
-			}
+			determineVelocity();
+			moveMoonsUsingVelocity();
 			
-			//System.out.println("Moons = "+Arrays.deepToString(moons));
-//			List<Integer> stuff = new ArrayList<>();
-//			stuff.addAll(Arrays.stream(moons).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
-//			stuff.addAll(Arrays.stream(velocity).flatMapToInt(e -> Arrays.stream(e)).boxed().collect(Collectors.toList()));
-//			if(n == 65976L || n == 45167L) {
-//				System.out.println(Arrays.toString(stuff.toArray()));
-//			}
-//			
-//			if(!set2.add(stuff)) {
-//				System.out.println("Stuff is filled!");
-//			}
 			for(int i = 0; i<sets.size(); i++) {
 				if(res[i] == 0 && !sets.get(i).add(Arrays.asList(moons[0][i], moons[1][i], moons[2][i], moons[3][i],velocity[0][i], velocity[1][i], velocity[2][i], velocity[3][i]))){
 					res[i] = n;
@@ -98,9 +47,33 @@ public Object part2() throws IOException {
 			}
 		}
 	}
+
+	private void moveMoonsUsingVelocity() {
+		for(int i = 0; i<moons.length; i++) {
+			for(int j = 0; j<moons[0].length; j++) {
+				moons[i][j]+=velocity[i][j];
+			}
+		}
+	}
+
+	private void determineVelocity() {
+		for(int i = 0; i<moons.length; i++) {
+			for(int j = i+1; j<moons.length; j++) {
+				for(int dim = 0; dim<moons[0].length; dim++) {
+					int moon1 = moons[i][dim], moon2 = moons[j][dim];
+					if(moon1 < moon2) {
+						velocity[i][dim]++;
+						velocity[j][dim]--;
+					} else if(moon1 > moon2) {
+						velocity[i][dim]--;
+						velocity[j][dim]++;
+					}
+				}
+			}
+		}
+	}
 	
-	private static long gcd(long a, long b)
-	{
+	private static long gcd(long a, long b) {
 	    while (b > 0)
 	    {
 	        long temp = b;
@@ -110,13 +83,11 @@ private static long gcd(long a, long b)
 	    return a;
 	}
 	
-	private static long lcm(long a, long b)
-	{
+	private static long lcm(long a, long b) {
 	    return a * (b / gcd(a, b));
 	}
 
-	private static long lcm(long[] input)
-	{
+	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;
@@ -129,30 +100,4 @@ short[][] copy(short[][] arr){
 		    myInt[i] = arr[i].clone();
 		return myInt;
 	}
-	
-	class Numbers{
-		short[][][] numbers;
-		
-		public Numbers(short[][][] nums) {
-			this.numbers=nums;
-		}
-
-		@Override
-		public int hashCode() {
-			return Arrays.deepHashCode(numbers);
-		}
-
-		@Override
-		public boolean equals(Object obj) {
-			Numbers other = (Numbers) obj;
-//			System.out.println(iter+", "+other.iter);
-			//System.out.println("Check deep equals "+toString()+" between "+other.toString());
-			return Arrays.deepEquals(numbers, other.numbers);
-		}
-
-		@Override
-		public String toString() {
-			return "Numbers [numbers=" + Arrays.deepToString(numbers) + "]";
-		}
-	}
 }

From ceec5c716bd9fb94ea21c1247156adc68db7d946 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 12 Dec 2019 08:30:40 +0100
Subject: [PATCH 063/120] Add day 12

---
 README.md                                           | 1 +
 src/main/java/com/sbaars/adventofcode2019/Main.java | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index e0516844..3e8c48ec 100644
--- a/README.md
+++ b/README.md
@@ -13,3 +13,4 @@ Days:
 - [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)
diff --git a/src/main/java/com/sbaars/adventofcode2019/Main.java b/src/main/java/com/sbaars/adventofcode2019/Main.java
index df476862..3c5219a9 100644
--- a/src/main/java/com/sbaars/adventofcode2019/Main.java
+++ b/src/main/java/com/sbaars/adventofcode2019/Main.java
@@ -7,7 +7,7 @@
 
 public class Main {
 	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException, InvocationTargetException, NoSuchMethodException {
-		for(int day = 1; day<=11; day++) {
+		for(int day = 1; day<=12; day++) {
 			System.out.println("Day "+day+":");
 			Day instance = (Day)Class.forName("com.sbaars.adventofcode2019.days.Day"+day).getDeclaredConstructor().newInstance();
 			instance.printParts();

From a5f5bdca624abe0899b41025fba429186717c963 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 13 Dec 2019 06:48:40 +0100
Subject: [PATCH 064/120] Day 13 Part 1 and 2

---
 .../sbaars/adventofcode2019/days/Day13.java   | 85 +++++++++++++++++++
 .../intcode/IntcodeComputer.java              | 11 ++-
 src/main/resources/day13.txt                  |  1 +
 3 files changed, 94 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day13.java
 create mode 100644 src/main/resources/day13.txt

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..8db6c6a4
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
@@ -0,0 +1,85 @@
+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 java.util.stream.Collectors;
+
+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<Point> n = new HashSet<Point>();
+		while(true) {
+			int x = cp.runInt();
+			if(x == IntcodeComputer.STOP_CODE) return n.size();
+			int y = cp.runInt();
+			if(y == IntcodeComputer.STOP_CODE) return n.size();
+			int tile = cp.runInt();
+			if(tile == IntcodeComputer.STOP_CODE) return n.size();
+			if(tile == 2)
+				n.add(new Point(x,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;
+		int n = 0;
+		int paddlePos = 0, ballPos = 0;
+		while(true) {
+			int x = cp.runInt();
+			if(x == IntcodeComputer.STOP_CODE)
+				return score;
+			int y = cp.runInt();
+			if(x == IntcodeComputer.STOP_CODE)
+				return score;
+			int tile = cp.runInt();
+			if(x == IntcodeComputer.STOP_CODE)
+				return score;
+			if(x == -1)
+				score = tile;
+			else {
+				field[y][x] = tile;
+				System.out.println("Set "+y+", "+x+" to "+tile);
+				if(tile == 2)
+					n++;
+				else if (tile == 3)
+					paddlePos = x;
+				else if (tile == 4) {
+					ballPos = x;
+					Arrays.stream(field).map(e -> Arrays.stream(e).mapToObj(Integer::toString).map(f -> f.replace("4", "â–ˆ")).collect(Collectors.joining())).forEach(System.out::println);
+				}
+			}
+			if(ballPos>paddlePos) cp.setInput(1);
+			else if(ballPos<paddlePos) cp.setInput(-1);
+			else cp.setInput(0);
+			/*if(x == 37 && y == 20) {
+				if(n == 0) {
+					return score;
+				}
+				n = 0;
+				Arrays.stream(field).map(e -> Arrays.stream(e).mapToObj(Integer::toString).map(f -> f.replace("4", "â–ˆ")).collect(Collectors.joining())).forEach(System.out::println);
+				System.out.println("enter input");
+			}*/
+		}
+	}
+	
+	public class Tile{
+		Point pos;
+		int element;
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 9523ec25..a1e45299 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -16,6 +16,7 @@ public class IntcodeComputer implements DoesFileOperations {
 	private int lastInput;
 	private long relativeBase = 0;
 	private static final int[] DO_NOT_TRANSFORM_FINAL_ARGUMENT = {1, 2, 3, 7, 8};
+	public static final int STOP_CODE = Integer.MIN_VALUE+1;
 	
 	public IntcodeComputer(int day, int...input) throws IOException {
 		this.program = Arrays.stream(readDay(day).split(",")).mapToLong(Long::parseLong).toArray();
@@ -29,7 +30,7 @@ public IntcodeComputer(int day, int...input) throws IOException {
 	
 	public long run() {
 		long result;
-		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == -1);
+		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == Integer.MIN_VALUE);
 		return result;
 	}
 
@@ -90,10 +91,10 @@ private long executeInstruction(long[] args, int instruction) {
 			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 -2;
+			case 99: return STOP_CODE;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
-		return -1;
+		return Integer.MIN_VALUE;
 	}
 	
 	private long parseComplexInstruction(int instruction) {
@@ -139,4 +140,8 @@ private int nParams(int instruction) {
 	public int runInt() {
 		return Math.toIntExact(run());
 	}
+
+	public void setElement(int i, long j) {
+		program[i] = j;
+	}
 }
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

From b0b2376022725f0811ce456ee19e3bad1ab83de2 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 13 Dec 2019 06:56:17 +0100
Subject: [PATCH 065/120] Refactor day 13

---
 .../sbaars/adventofcode2019/days/Day13.java   | 61 +++++++------------
 1 file changed, 23 insertions(+), 38 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day13.java b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
index 8db6c6a4..d3b4fea7 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
@@ -2,10 +2,9 @@
 
 import java.awt.Point;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.stream.Collectors;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
@@ -24,9 +23,7 @@ public Object part1() throws IOException {
 			int x = cp.runInt();
 			if(x == IntcodeComputer.STOP_CODE) return n.size();
 			int y = cp.runInt();
-			if(y == IntcodeComputer.STOP_CODE) return n.size();
 			int tile = cp.runInt();
-			if(tile == IntcodeComputer.STOP_CODE) return n.size();
 			if(tile == 2)
 				n.add(new Point(x,y));
 		}
@@ -38,48 +35,36 @@ public Object part2() throws IOException {
 		cp.setElement(0, 2);
 		int[][] field = new int[21][38];
 		int score = 0;
-		int n = 0;
-		int paddlePos = 0, ballPos = 0;
+		AtomicInteger paddlePos = new AtomicInteger(), ballPos = new AtomicInteger();
 		while(true) {
 			int x = cp.runInt();
 			if(x == IntcodeComputer.STOP_CODE)
 				return score;
 			int y = cp.runInt();
-			if(x == IntcodeComputer.STOP_CODE)
-				return score;
 			int tile = cp.runInt();
-			if(x == IntcodeComputer.STOP_CODE)
-				return score;
-			if(x == -1)
-				score = tile;
-			else {
-				field[y][x] = tile;
-				System.out.println("Set "+y+", "+x+" to "+tile);
-				if(tile == 2)
-					n++;
-				else if (tile == 3)
-					paddlePos = x;
-				else if (tile == 4) {
-					ballPos = x;
-					Arrays.stream(field).map(e -> Arrays.stream(e).mapToObj(Integer::toString).map(f -> f.replace("4", "â–ˆ")).collect(Collectors.joining())).forEach(System.out::println);
-				}
+			score = simulateField(cp, field, score, paddlePos, ballPos, x, y, 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));
 			}
-			if(ballPos>paddlePos) cp.setInput(1);
-			else if(ballPos<paddlePos) cp.setInput(-1);
-			else cp.setInput(0);
-			/*if(x == 37 && y == 20) {
-				if(n == 0) {
-					return score;
-				}
-				n = 0;
-				Arrays.stream(field).map(e -> Arrays.stream(e).mapToObj(Integer::toString).map(f -> f.replace("4", "â–ˆ")).collect(Collectors.joining())).forEach(System.out::println);
-				System.out.println("enter input");
-			}*/
 		}
+		return score;
 	}
-	
-	public class Tile{
-		Point pos;
-		int element;
+
+	private int provideInput(AtomicInteger paddlePos, AtomicInteger ballPos) {
+		int ball = ballPos.get(), paddle = paddlePos.get();
+		if(ball>paddle) return 1;
+		else if(ball<paddle) return -1;
+		else return 0;
 	}
 }

From e0173a5562d1e58213239caad851d1f25760b582 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 13 Dec 2019 07:02:55 +0100
Subject: [PATCH 066/120] Finishing up for today

---
 README.md                                     | 56 +++++++++++++++++++
 .../com/sbaars/adventofcode2019/Main.java     |  2 +-
 .../sbaars/adventofcode2019/days/Day11.java   |  4 +-
 .../sbaars/adventofcode2019/days/Day7.java    |  2 +-
 src/main/resources/day4.txt                   |  1 +
 .../sbaars/adventofcode2019/IntcodeTest.java  | 12 ++++
 6 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 src/main/resources/day4.txt

diff --git a/README.md b/README.md
index 3e8c48ec..23e30683 100644
--- a/README.md
+++ b/README.md
@@ -14,3 +14,59 @@ Days:
 - [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)
+
+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: FPUAR
+
+Day 9:
+Part 1: 2518058886
+Part 2: 44292
+
+Day 10:
+Part 1: 299
+Part 2: 1419
+
+Day 11:
+Part 1: 2172
+Part 2: JELEFGHP
+
+Day 12:
+Part 1: 13399
+Part 2: 312992287193064
+
+Day 13:
+Part 1: 320
+Part 2: 15156
+```
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/Main.java b/src/main/java/com/sbaars/adventofcode2019/Main.java
index 3c5219a9..59227840 100644
--- a/src/main/java/com/sbaars/adventofcode2019/Main.java
+++ b/src/main/java/com/sbaars/adventofcode2019/Main.java
@@ -7,7 +7,7 @@
 
 public class Main {
 	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException, InvocationTargetException, NoSuchMethodException {
-		for(int day = 1; day<=12; day++) {
+		for(int day = 1; day<=13; day++) {
 			System.out.println("Day "+day+":");
 			Day instance = (Day)Class.forName("com.sbaars.adventofcode2019.days.Day"+day).getDeclaredConstructor().newInstance();
 			instance.printParts();
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 3b49d2a6..d5a12a94 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -34,11 +34,9 @@ private Object robotWalk(boolean startWhite) throws IOException {
 		while(true) {
 			c.setInput(whitePlaces.contains(currentLocation) ? 1 : 0);
 			int paintColor = c.runInt();
-			if(paintColor == -2)
+			if(paintColor == IntcodeComputer.STOP_CODE)
 				break;
 			int turn = c.runInt();
-			if(turn == -2)
-				break;
 			paintedOnce.add(currentLocation);
 			if(paintColor == 1) {
 				whitePlaces.add(currentLocation);
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 530975e3..a1af8316 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -41,7 +41,7 @@ public Object part2() throws IOException {
 					c.addInput(lastVal);
 					int thruster = lastVal;
 					lastVal = c.runInt();
-					if(lastVal == -2) {
+					if(lastVal == IntcodeComputer.STOP_CODE) {
 						results.add(thruster);
 						continue perms;
 					}
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/test/java/com/sbaars/adventofcode2019/IntcodeTest.java b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
index 04ad01b3..6199e99a 100644
--- a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -2,6 +2,8 @@
 
 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;
@@ -30,4 +32,14 @@ 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());
+	}
+	
+	public void testDay13() throws IOException {
+		Assert.assertEquals(320, new Day13().part1());
+		Assert.assertEquals(15156, new Day13().part2());
+	}
 }

From fc5baa9db63ed2f2e329e91e54f7eb27b81217be Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 13 Dec 2019 07:05:03 +0100
Subject: [PATCH 067/120] Fixed a failing test

---
 src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
index 6199e99a..5e91b170 100644
--- a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -35,7 +35,7 @@ public void testDay9() throws IOException {
 	
 	public void testDay11() throws IOException {
 		Assert.assertEquals(2172, new Day11().part1());
-		Assert.assertEquals("JELEFGHP", new Day11().part2());
+		Assert.assertEquals("JELEFGHP", new Day11().part2().toString());
 	}
 	
 	public void testDay13() throws IOException {

From dde43011d9abf72272adaf660f3b2ca5cadd3970 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 06:57:48 +0100
Subject: [PATCH 068/120] Day 14 part 1

---
 .../sbaars/adventofcode2019/days/Day14.java   | 91 +++++++++++++++++++
 src/main/resources/day14.txt                  | 60 ++++++++++++
 src/main/resources/day15.txt                  |  9 ++
 3 files changed, 160 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day14.java
 create mode 100644 src/main/resources/day14.txt
 create mode 100644 src/main/resources/day15.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
new file mode 100644
index 00000000..20b82189
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -0,0 +1,91 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map.Entry;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.CountMap;
+
+public class Day14 implements Day {
+	public static void main(String[] args) throws IOException {
+		new Day14().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
+		CountMap<String> items = new CountMap<>();
+		for(int i = 13311; i<15000; i++) {
+			System.out.println("We now have "+i+" ORE");
+			items.put("ORE", i);
+			if(i == 14000) {
+				System.out.println("Hi");
+			}
+			if(canMakeFuel(trades, items)) {
+				return i;
+			}
+		}
+		return 0;
+	}
+	
+	private boolean canMakeFuel(Trade[] trades, CountMap<String> items) {
+		//System.out.println(items);
+		//System.out.println("----");
+		for(Trade trade : trades) {
+			CountMap<String> newItems = new CountMap<>(items);
+			if(trade.perform(newItems)) {
+				if(trade.output.item.equals("FUEL")) {
+					return true;
+				}
+				if(canMakeFuel(trades, newItems))
+					return true;
+			}
+		}
+		return false;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		return 0;
+	}
+	
+	class Trade {
+		CountMap<String> input = new CountMap<>();
+		Item output;
+		
+		public Trade(String trade) {
+			String[] inputOutput = trade.split(" => ");
+			Arrays.stream(inputOutput[0].split(", ")).map(Item::new).forEach(e -> input.increment(e.item, e.amount));
+			output = new Item(inputOutput[1]);
+		}
+		
+		public boolean perform(CountMap<String> items) {
+			for(Entry<String, Integer> item : input.entrySet()) {
+				if(!items.containsKey(item.getKey()) || items.get(item.getKey()) < item.getValue())
+					return false;
+				else {
+					items.increment(item.getKey(), -item.getValue());
+				}
+			}
+			items.increment(output.item, output.amount);
+			return true;
+		}
+	}
+	
+	class Item {
+		int amount;
+		String item;
+		
+		public Item(String item) {
+			String[] i = item.split(" ");
+			amount = Integer.parseInt(i[0]);
+			this.item = i[1];
+		}
+
+		public Item(int i, String string) {
+			amount = i;
+			item = string;
+		}
+	}
+}
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..fe064792
--- /dev/null
+++ b/src/main/resources/day15.txt
@@ -0,0 +1,9 @@
+157 ORE => 5 NZVS
+165 ORE => 6 DCFZ
+44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
+12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
+179 ORE => 7 PSHF
+177 ORE => 5 HKGWZ
+7 DCFZ, 7 PSHF => 2 XJWVT
+165 ORE => 2 GPVTF
+3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT
\ No newline at end of file

From 2f1fc483e426440d79dc6f66361285500d3f396e Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 07:53:04 +0100
Subject: [PATCH 069/120] Part 1 different approach

---
 .../sbaars/adventofcode2019/days/Day14.java   | 31 ++++++++++++++++---
 .../adventofcode2019/util/CountMap.java       |  6 ++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 20b82189..67a3153d 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -15,7 +15,9 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
-		CountMap<String> items = new CountMap<>();
+		return findCost(trades, getTrade(trades, "FUEL"), 1);
+		//return Arrays.stream(trades).map(e -> e.output.item).distinct().count();
+		/*CountMap<String> items = new CountMap<>();
 		for(int i = 13311; i<15000; i++) {
 			System.out.println("We now have "+i+" ORE");
 			items.put("ORE", i);
@@ -26,13 +28,34 @@ public Object part1() throws IOException {
 				return i;
 			}
 		}
-		return 0;
+		return 0;*/
+	}
+
+	private Trade getTrade(Trade[] trades, String key) {
+		return Arrays.stream(trades).filter(e -> e.output.item.equals(key)).findAny().get();
 	}
 	
+	private int findCost(Trade[] trades, Trade fuelTrade, int nNeeded) {
+		int timesApplied = (int)Math.ceil((double)nNeeded/(double)fuelTrade.output.amount);
+		int totalCost = 0;
+		for(Entry<String, Integer> cost : fuelTrade.input.entrySet()) {
+			if(cost.getKey().equals("ORE")) {
+				totalCost+=cost.getValue();
+			} else {
+				totalCost+=findCost(trades, getTrade(trades, cost.getKey()), cost.getValue());
+			}
+		}
+		System.out.println(fuelTrade.output.item+" costs "+totalCost+" times "+timesApplied+" needed "+nNeeded);
+		return totalCost * timesApplied;
+	}
+
 	private boolean canMakeFuel(Trade[] trades, CountMap<String> items) {
 		//System.out.println(items);
 		//System.out.println("----");
-		for(Trade trade : trades) {
+		//Trade fuelTrade = Arrays.stream(trades).filter(e -> e.output.item.equals("FUEL")).findAny().get();
+		//findCost
+		
+		/*for(Trade trade : trades) {
 			CountMap<String> newItems = new CountMap<>(items);
 			if(trade.perform(newItems)) {
 				if(trade.output.item.equals("FUEL")) {
@@ -41,7 +64,7 @@ private boolean canMakeFuel(Trade[] trades, CountMap<String> items) {
 				if(canMakeFuel(trades, newItems))
 					return true;
 			}
-		}
+		}*/
 		return false;
 	}
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java b/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
index 7b822c09..5eb6543b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
+++ b/src/main/java/com/sbaars/adventofcode2019/util/CountMap.java
@@ -49,4 +49,10 @@ public String toString() {
 	public void addAll(CountMap<K> amountPerCloneClassSize) {
 		amountPerCloneClassSize.entrySet().stream().forEach(e -> this.increment(e.getKey(), e.getValue()));
 	}
+
+	public void incrementAll(CountMap<K> input) {
+		for(Entry<K, Integer> i : input.entrySet()) {
+			increment(i.getKey(), i.getValue());
+		}
+	}
 }

From e145e108810f396f7fadb1c1cd88e9ac81a44b41 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 09:19:18 +0100
Subject: [PATCH 070/120] Skip on leftover

---
 .../sbaars/adventofcode2019/days/Day14.java   | 84 +++++++++----------
 src/main/resources/day16.txt                  | 12 +++
 2 files changed, 52 insertions(+), 44 deletions(-)
 create mode 100644 src/main/resources/day16.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 67a3153d..6ed2f311 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -2,7 +2,6 @@
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Map.Entry;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.CountMap;
@@ -15,7 +14,9 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
-		return findCost(trades, getTrade(trades, "FUEL"), 1);
+		int cost = findCost(trades, new Item(1, "FUEL"), new CountMap<>());
+		System.out.println(created);
+		return cost;
 		//return Arrays.stream(trades).map(e -> e.output.item).distinct().count();
 		/*CountMap<String> items = new CountMap<>();
 		for(int i = 13311; i<15000; i++) {
@@ -35,37 +36,34 @@ private Trade getTrade(Trade[] trades, String key) {
 		return Arrays.stream(trades).filter(e -> e.output.item.equals(key)).findAny().get();
 	}
 	
-	private int findCost(Trade[] trades, Trade fuelTrade, int nNeeded) {
-		int timesApplied = (int)Math.ceil((double)nNeeded/(double)fuelTrade.output.amount);
-		int totalCost = 0;
-		for(Entry<String, Integer> cost : fuelTrade.input.entrySet()) {
-			if(cost.getKey().equals("ORE")) {
-				totalCost+=cost.getValue();
-			} else {
-				totalCost+=findCost(trades, getTrade(trades, cost.getKey()), cost.getValue());
-			}
-		}
-		System.out.println(fuelTrade.output.item+" costs "+totalCost+" times "+timesApplied+" needed "+nNeeded);
-		return totalCost * timesApplied;
-	}
-
-	private boolean canMakeFuel(Trade[] trades, CountMap<String> items) {
-		//System.out.println(items);
-		//System.out.println("----");
-		//Trade fuelTrade = Arrays.stream(trades).filter(e -> e.output.item.equals("FUEL")).findAny().get();
-		//findCost
+	CountMap<String> created = new CountMap<>();
+	private int findCost(Trade[] trades, Item buyingItem, CountMap<String> leftOver) {
+		Trade fuelTrade = getTrade(trades, buyingItem.item);
+		int timesApplied = (int)Math.ceil((double)buyingItem.amount/(double)fuelTrade.output.amount);
+		leftOver.increment(fuelTrade.output.item, buyingItem.amount % fuelTrade.output.amount);
 		
-		/*for(Trade trade : trades) {
-			CountMap<String> newItems = new CountMap<>(items);
-			if(trade.perform(newItems)) {
-				if(trade.output.item.equals("FUEL")) {
-					return true;
+		//System.out.println(fuelTrade.output.item+" nLeftOver "+leftOver.get(fuelTrade.output.item));
+		int totalCost = 0;
+		for(int i = 0; i<timesApplied; i++) {			
+			for(Item cost : fuelTrade.input) {
+				if(leftOver.get(cost.item) >= cost.amount) {
+					leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
+					//skip = fuelTrade.output.item;
+					System.out.println("Enough "+fuelTrade.output.item+" LEFTOVER!");
+					continue;
+				}
+				if(cost.item.equals("ORE")) {
+					totalCost+=cost.amount;
+					System.out.println("Spend "+cost.amount+" ORE to get "+fuelTrade.output.amount+" "+fuelTrade.output.item);
+				} else {
+					totalCost+=findCost(trades, new Item(cost.amount, cost.item), leftOver);
 				}
-				if(canMakeFuel(trades, newItems))
-					return true;
 			}
-		}*/
-		return false;
+			created.increment(buyingItem.item, fuelTrade.output.amount);
+		}
+		System.out.println("Bought "+(timesApplied*fuelTrade.output.amount)+" "+buyingItem.item+" for "+totalCost);
+		//System.out.println(fuelTrade.output.item+" costs "+totalCost+" times "+timesApplied);
+		return totalCost;
 	}
 	
 	@Override
@@ -74,25 +72,18 @@ public Object part2() throws IOException {
 	}
 	
 	class Trade {
-		CountMap<String> input = new CountMap<>();
-		Item output;
+		final Item[] input;
+		final Item output;
 		
 		public Trade(String trade) {
 			String[] inputOutput = trade.split(" => ");
-			Arrays.stream(inputOutput[0].split(", ")).map(Item::new).forEach(e -> input.increment(e.item, e.amount));
+			input = Arrays.stream(inputOutput[0].split(", ")).map(Item::new).toArray(Item[]::new);
 			output = new Item(inputOutput[1]);
 		}
-		
-		public boolean perform(CountMap<String> items) {
-			for(Entry<String, Integer> item : input.entrySet()) {
-				if(!items.containsKey(item.getKey()) || items.get(item.getKey()) < item.getValue())
-					return false;
-				else {
-					items.increment(item.getKey(), -item.getValue());
-				}
-			}
-			items.increment(output.item, output.amount);
-			return true;
+
+		@Override
+		public String toString() {
+			return "Trade [input=" + Arrays.toString(input) + ", output=" + output + "]";
 		}
 	}
 	
@@ -110,5 +101,10 @@ public Item(int i, String string) {
 			amount = i;
 			item = string;
 		}
+
+		@Override
+		public String toString() {
+			return "Item [amount=" + amount + ", item=" + item + "]";
+		}
 	}
 }
diff --git a/src/main/resources/day16.txt b/src/main/resources/day16.txt
new file mode 100644
index 00000000..7c1333b1
--- /dev/null
+++ b/src/main/resources/day16.txt
@@ -0,0 +1,12 @@
+2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
+17 NVRVD, 3 JNWZP => 8 VPVL
+53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
+22 VJHF, 37 MNCFX => 5 FWMGM
+139 ORE => 4 NVRVD
+144 ORE => 7 JNWZP
+5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC
+5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV
+145 ORE => 6 MNCFX
+1 NVRVD => 8 CXFTF
+1 VJHF, 6 MNCFX => 4 RFSQX
+176 ORE => 6 VJHF
\ No newline at end of file

From 6cdd2be649f17cbbb08ea7512e1fa033b4bd2434 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 10:43:08 +0100
Subject: [PATCH 071/120] Okay

---
 .../sbaars/adventofcode2019/days/Day14.java   | 66 ++++++++++++++-----
 src/main/resources/day17.txt                  |  7 ++
 2 files changed, 56 insertions(+), 17 deletions(-)
 create mode 100644 src/main/resources/day17.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 6ed2f311..5bb048a7 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -38,33 +38,65 @@ private Trade getTrade(Trade[] trades, String key) {
 	
 	CountMap<String> created = new CountMap<>();
 	private int findCost(Trade[] trades, Item buyingItem, CountMap<String> leftOver) {
+		if(buyingItem.item.equals("ORE"))
+			return buyingItem.amount;
 		Trade fuelTrade = getTrade(trades, buyingItem.item);
 		int timesApplied = (int)Math.ceil((double)buyingItem.amount/(double)fuelTrade.output.amount);
-		leftOver.increment(fuelTrade.output.item, buyingItem.amount % fuelTrade.output.amount);
 		
-		//System.out.println(fuelTrade.output.item+" nLeftOver "+leftOver.get(fuelTrade.output.item));
+		System.out.println("Buy "+timesApplied+"x"+fuelTrade.output.amount+" "+buyingItem.item);
+		
+		/*if(leftOver.get(fuelTrade.output.item) >= fuelTrade.output.amount) {
+			System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
+			leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
+			System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
+			//skip = fuelTrade.output.item;
+			//System.out.println("Enough "+fuelTrade.output.item+" !");
+			timesApplied--;
+			//return 0; //You have this material, so you get it for free :)
+		}*/
+		//leftOver.increment(fuelTrade.output.item, buyingItem.amount % fuelTrade.output.amount);
+		
 		int totalCost = 0;
-		for(int i = 0; i<timesApplied; i++) {			
-			for(Item cost : fuelTrade.input) {
-				if(leftOver.get(cost.item) >= cost.amount) {
-					leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
-					//skip = fuelTrade.output.item;
-					System.out.println("Enough "+fuelTrade.output.item+" LEFTOVER!");
-					continue;
-				}
-				if(cost.item.equals("ORE")) {
-					totalCost+=cost.amount;
-					System.out.println("Spend "+cost.amount+" ORE to get "+fuelTrade.output.amount+" "+fuelTrade.output.item);
-				} else {
-					totalCost+=findCost(trades, new Item(cost.amount, cost.item), leftOver);
-				}
-			}
+		for(int i = 0; i<timesApplied; i++) {	
+			/*if(leftOver.get(fuelTrade.output.item) >= fuelTrade.output.amount) {
+				System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
+				leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
+				System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
+				//skip = fuelTrade.output.item;
+				System.out.println("Enough "+fuelTrade.output.item+" LEFTOVER!");
+				continue;
+			}*/
+			totalCost = applyTrade(trades, fuelTrade, totalCost, leftOver);
 			created.increment(buyingItem.item, fuelTrade.output.amount);
 		}
+		
+		leftOver.increment(buyingItem.item, buyingItem.amount % fuelTrade.output.amount);
+		System.out.println(fuelTrade.output.item+" nLeftOver "+leftOver.get(fuelTrade.output.item));
 		System.out.println("Bought "+(timesApplied*fuelTrade.output.amount)+" "+buyingItem.item+" for "+totalCost);
 		//System.out.println(fuelTrade.output.item+" costs "+totalCost+" times "+timesApplied);
 		return totalCost;
 	}
+
+	private int applyTrade(Trade[] trades, Trade fuelTrade, int totalCost, CountMap<String> leftOver) {
+		for(Item cost : fuelTrade.input) {
+			/*if(leftOver.get(cost.item) >= cost.amount) {
+				//System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
+				leftOver.increment(cost.item, -cost.amount);
+				//System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
+				//skip = fuelTrade.output.item;
+				//System.out.println("Enough "+fuelTrade.output.item+" !");
+				continue; //You have this material, so you get it for free :)
+			}*/
+			if(cost.item.equals("ORE")) {
+				totalCost+=cost.amount;
+				System.out.println("Spend "+cost.amount+" ORE to get "+fuelTrade.output.amount+" "+fuelTrade.output.item+" in trade "+fuelTrade);
+			} else {
+				totalCost+=findCost(trades, new Item(cost.amount, cost.item), leftOver);
+				//leftOver.increment(fuelTrade.output.item, cost.amount % fuelTrade.output.amount);
+			}
+		}
+		return totalCost;
+	}
 	
 	@Override
 	public Object part2() throws IOException {
diff --git a/src/main/resources/day17.txt b/src/main/resources/day17.txt
new file mode 100644
index 00000000..80a5907e
--- /dev/null
+++ b/src/main/resources/day17.txt
@@ -0,0 +1,7 @@
+9 ORE => 2 A
+8 ORE => 3 B
+7 ORE => 5 C
+3 A, 4 B => 1 AB
+5 B, 7 C => 1 BC
+4 C, 1 A => 1 CA
+2 AB, 3 BC, 4 CA => 1 FUEL
\ No newline at end of file

From bd9ff02869c807a987c44c9dedd79411012ac743 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 10:53:13 +0100
Subject: [PATCH 072/120] Well

---
 .../sbaars/adventofcode2019/days/Day14.java   | 40 ++++++++++++-------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 5bb048a7..48af6bdc 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -13,9 +13,9 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public Object part1() throws IOException {
-		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
+		Trade[] trades = Arrays.stream(readDay(14).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
 		int cost = findCost(trades, new Item(1, "FUEL"), new CountMap<>());
-		System.out.println(created);
+		//System.out.println(created);
 		return cost;
 		//return Arrays.stream(trades).map(e -> e.output.item).distinct().count();
 		/*CountMap<String> items = new CountMap<>();
@@ -40,10 +40,17 @@ private Trade getTrade(Trade[] trades, String key) {
 	private int findCost(Trade[] trades, Item buyingItem, CountMap<String> 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, 0);
+		
 		Trade fuelTrade = getTrade(trades, buyingItem.item);
 		int timesApplied = (int)Math.ceil((double)buyingItem.amount/(double)fuelTrade.output.amount);
 		
-		System.out.println("Buy "+timesApplied+"x"+fuelTrade.output.amount+" "+buyingItem.item);
+		//System.out.println("Buy "+timesApplied+"x"+fuelTrade.output.amount+" "+buyingItem.item);
 		
 		/*if(leftOver.get(fuelTrade.output.item) >= fuelTrade.output.amount) {
 			System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
@@ -57,7 +64,10 @@ private int findCost(Trade[] trades, Item buyingItem, CountMap<String> leftOver)
 		//leftOver.increment(fuelTrade.output.item, buyingItem.amount % fuelTrade.output.amount);
 		
 		int totalCost = 0;
-		for(int i = 0; i<timesApplied; i++) {	
+		for(Item cost : fuelTrade.input) {
+			totalCost+=findCost(trades, new Item(cost.amount*timesApplied, cost.item), leftOver);
+		}
+		//for(int i = 0; i<timesApplied; i++) {	
 			/*if(leftOver.get(fuelTrade.output.item) >= fuelTrade.output.amount) {
 				System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
 				leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
@@ -66,13 +76,13 @@ private int findCost(Trade[] trades, Item buyingItem, CountMap<String> leftOver)
 				System.out.println("Enough "+fuelTrade.output.item+" LEFTOVER!");
 				continue;
 			}*/
-			totalCost = applyTrade(trades, fuelTrade, totalCost, leftOver);
-			created.increment(buyingItem.item, fuelTrade.output.amount);
-		}
+			//totalCost = applyTrade(trades, fuelTrade, totalCost, leftOver);
+			//created.increment(buyingItem.item, fuelTrade.output.amount);
+		//}
 		
-		leftOver.increment(buyingItem.item, buyingItem.amount % fuelTrade.output.amount);
-		System.out.println(fuelTrade.output.item+" nLeftOver "+leftOver.get(fuelTrade.output.item));
-		System.out.println("Bought "+(timesApplied*fuelTrade.output.amount)+" "+buyingItem.item+" for "+totalCost);
+		leftOver.increment(buyingItem.item, fuelTrade.output.amount * timesApplied - buyingItem.amount);
+		//System.out.println(fuelTrade.output.item+" nLeftOver "+leftOver.get(fuelTrade.output.item));
+		//System.out.println("Bought "+(timesApplied*fuelTrade.output.amount)+" "+buyingItem.item+" for "+totalCost);
 		//System.out.println(fuelTrade.output.item+" costs "+totalCost+" times "+timesApplied);
 		return totalCost;
 	}
@@ -87,13 +97,13 @@ private int applyTrade(Trade[] trades, Trade fuelTrade, int totalCost, CountMap<
 				//System.out.println("Enough "+fuelTrade.output.item+" !");
 				continue; //You have this material, so you get it for free :)
 			}*/
-			if(cost.item.equals("ORE")) {
-				totalCost+=cost.amount;
-				System.out.println("Spend "+cost.amount+" ORE to get "+fuelTrade.output.amount+" "+fuelTrade.output.item+" in trade "+fuelTrade);
-			} else {
+			//if(cost.item.equals("ORE")) {
+			//	totalCost+=cost.amount;
+			//	System.out.println("Spend "+cost.amount+" ORE to get "+fuelTrade.output.amount+" "+fuelTrade.output.item+" in trade "+fuelTrade);
+			//} else {
 				totalCost+=findCost(trades, new Item(cost.amount, cost.item), leftOver);
 				//leftOver.increment(fuelTrade.output.item, cost.amount % fuelTrade.output.amount);
-			}
+			//}
 		}
 		return totalCost;
 	}

From ddebc538658d563fcde9df22a3861106cbf15612 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 10:55:07 +0100
Subject: [PATCH 073/120] Cleanup

---
 .../sbaars/adventofcode2019/days/Day14.java   | 75 ++-----------------
 1 file changed, 6 insertions(+), 69 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 48af6bdc..5fabc7c2 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -14,22 +14,7 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		Trade[] trades = Arrays.stream(readDay(14).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
-		int cost = findCost(trades, new Item(1, "FUEL"), new CountMap<>());
-		//System.out.println(created);
-		return cost;
-		//return Arrays.stream(trades).map(e -> e.output.item).distinct().count();
-		/*CountMap<String> items = new CountMap<>();
-		for(int i = 13311; i<15000; i++) {
-			System.out.println("We now have "+i+" ORE");
-			items.put("ORE", i);
-			if(i == 14000) {
-				System.out.println("Hi");
-			}
-			if(canMakeFuel(trades, items)) {
-				return i;
-			}
-		}
-		return 0;*/
+		return findCost(trades, new Item(1, "FUEL"), new CountMap<>());
 	}
 
 	private Trade getTrade(Trade[] trades, String key) {
@@ -47,64 +32,16 @@ else if(buyingItem.amount <= leftOver.get(buyingItem.item)) {
 		buyingItem.amount-=leftOver.get(buyingItem.item);
 		leftOver.put(buyingItem.item, 0);
 		
+		return performTrade(trades, buyingItem, leftOver);
+	}
+
+	private int performTrade(Trade[] trades, Item buyingItem, CountMap<String> leftOver) {
 		Trade fuelTrade = getTrade(trades, buyingItem.item);
 		int timesApplied = (int)Math.ceil((double)buyingItem.amount/(double)fuelTrade.output.amount);
-		
-		//System.out.println("Buy "+timesApplied+"x"+fuelTrade.output.amount+" "+buyingItem.item);
-		
-		/*if(leftOver.get(fuelTrade.output.item) >= fuelTrade.output.amount) {
-			System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
-			leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
-			System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
-			//skip = fuelTrade.output.item;
-			//System.out.println("Enough "+fuelTrade.output.item+" !");
-			timesApplied--;
-			//return 0; //You have this material, so you get it for free :)
-		}*/
-		//leftOver.increment(fuelTrade.output.item, buyingItem.amount % fuelTrade.output.amount);
-		
 		int totalCost = 0;
-		for(Item cost : fuelTrade.input) {
+		for(Item cost : fuelTrade.input)
 			totalCost+=findCost(trades, new Item(cost.amount*timesApplied, cost.item), leftOver);
-		}
-		//for(int i = 0; i<timesApplied; i++) {	
-			/*if(leftOver.get(fuelTrade.output.item) >= fuelTrade.output.amount) {
-				System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
-				leftOver.increment(fuelTrade.output.item, -fuelTrade.output.amount);
-				System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
-				//skip = fuelTrade.output.item;
-				System.out.println("Enough "+fuelTrade.output.item+" LEFTOVER!");
-				continue;
-			}*/
-			//totalCost = applyTrade(trades, fuelTrade, totalCost, leftOver);
-			//created.increment(buyingItem.item, fuelTrade.output.amount);
-		//}
-		
 		leftOver.increment(buyingItem.item, fuelTrade.output.amount * timesApplied - buyingItem.amount);
-		//System.out.println(fuelTrade.output.item+" nLeftOver "+leftOver.get(fuelTrade.output.item));
-		//System.out.println("Bought "+(timesApplied*fuelTrade.output.amount)+" "+buyingItem.item+" for "+totalCost);
-		//System.out.println(fuelTrade.output.item+" costs "+totalCost+" times "+timesApplied);
-		return totalCost;
-	}
-
-	private int applyTrade(Trade[] trades, Trade fuelTrade, int totalCost, CountMap<String> leftOver) {
-		for(Item cost : fuelTrade.input) {
-			/*if(leftOver.get(cost.item) >= cost.amount) {
-				//System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
-				leftOver.increment(cost.item, -cost.amount);
-				//System.out.println("Leftover "+fuelTrade.output.item+" = "+leftOver.get(fuelTrade.output.item)+" for trade "+fuelTrade);
-				//skip = fuelTrade.output.item;
-				//System.out.println("Enough "+fuelTrade.output.item+" !");
-				continue; //You have this material, so you get it for free :)
-			}*/
-			//if(cost.item.equals("ORE")) {
-			//	totalCost+=cost.amount;
-			//	System.out.println("Spend "+cost.amount+" ORE to get "+fuelTrade.output.amount+" "+fuelTrade.output.item+" in trade "+fuelTrade);
-			//} else {
-				totalCost+=findCost(trades, new Item(cost.amount, cost.item), leftOver);
-				//leftOver.increment(fuelTrade.output.item, cost.amount % fuelTrade.output.amount);
-			//}
-		}
 		return totalCost;
 	}
 	

From 979c2586136bb5383072dd3ba9a4fb71a581b726 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 11:29:05 +0100
Subject: [PATCH 074/120] Part 2

---
 .../sbaars/adventofcode2019/days/Day14.java   | 25 ++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 5fabc7c2..cd9842de 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -2,6 +2,8 @@
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.CountMap;
@@ -47,7 +49,28 @@ private int performTrade(Trade[] trades, Item buyingItem, CountMap<String> leftO
 	
 	@Override
 	public Object part2() throws IOException {
-		return 0;
+		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
+		CountMap<String> leftOver = new CountMap<>();
+		long ore = 1000000000000L;
+		int fuel = 0;
+		Map<CountMap<String>, Integer> res = new HashMap<>();
+		int found = 0, notFound = 0;
+		while(true) {
+			if(!res.containsKey(leftOver)) {
+				int cost = findCost(trades, new Item(1, "FUEL"), leftOver);
+				res.put(new CountMap<>(leftOver), cost);
+				ore-=cost;
+				found++;
+			} else {
+				ore-=res.get(leftOver);
+				notFound++;
+			}
+			if(ore>=0) {
+				fuel++;
+			} else break;
+		}
+		System.out.println("Found "+found+", notFound "+notFound);
+		return fuel;
 	}
 	
 	class Trade {

From 12d1f7939c2774c645c2e923ba4ec28317a71b67 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 11:41:52 +0100
Subject: [PATCH 075/120] Day 14 Part 2

Will optimize later
---
 .../sbaars/adventofcode2019/days/Day14.java   | 30 ++++++++-----------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index cd9842de..214bc498 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -2,8 +2,6 @@
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.CountMap;
@@ -15,6 +13,10 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public Object part1() throws IOException {
+		return findCosts();
+	}
+
+	private int findCosts() throws IOException {
 		Trade[] trades = Arrays.stream(readDay(14).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
 		return findCost(trades, new Item(1, "FUEL"), new CountMap<>());
 	}
@@ -51,25 +53,19 @@ private int performTrade(Trade[] trades, Item buyingItem, CountMap<String> leftO
 	public Object part2() throws IOException {
 		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
 		CountMap<String> leftOver = new CountMap<>();
-		long ore = 1000000000000L;
 		int fuel = 0;
-		Map<CountMap<String>, Integer> res = new HashMap<>();
-		int found = 0, notFound = 0;
-		while(true) {
-			if(!res.containsKey(leftOver)) {
-				int cost = findCost(trades, new Item(1, "FUEL"), leftOver);
-				res.put(new CountMap<>(leftOver), cost);
-				ore-=cost;
-				found++;
+		
+		for(long ore = 1000000000000L, amount = ore / findCosts(); ore>0 && amount>0; ) {
+			CountMap<String> newLeftOver = new CountMap<>(leftOver);
+			int cost = findCost(trades, new Item(1, "FUEL"), newLeftOver);
+			if(cost > ore) {
+				amount /= 2;	
 			} else {
-				ore-=res.get(leftOver);
-				notFound++;
+				fuel += amount;
+				ore -= cost;
+				leftOver = newLeftOver;
 			}
-			if(ore>=0) {
-				fuel++;
-			} else break;
 		}
-		System.out.println("Found "+found+", notFound "+notFound);
 		return fuel;
 	}
 	

From c25113713197227159393f0e2f0a1ba4210c3214 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 22:43:24 +0100
Subject: [PATCH 076/120] Day 14 Refactor

---
 .../sbaars/adventofcode2019/days/Day14.java   | 72 ++++++++-----------
 .../adventofcode2019/util/LongCountMap.java   | 58 +++++++++++++++
 2 files changed, 88 insertions(+), 42 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/util/LongCountMap.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 214bc498..2154a2bf 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -4,9 +4,15 @@
 import java.util.Arrays;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.util.CountMap;
+import com.sbaars.adventofcode2019.util.LongCountMap;
 
 public class Day14 implements Day {
+	private Trade[] trades;
+	
+	public Day14() throws IOException {
+		this.trades = Arrays.stream(readDay(14).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
+	}
+	
 	public static void main(String[] args) throws IOException {
 		new Day14().printParts();
 	}
@@ -16,17 +22,15 @@ public Object part1() throws IOException {
 		return findCosts();
 	}
 
-	private int findCosts() throws IOException {
-		Trade[] trades = Arrays.stream(readDay(14).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
-		return findCost(trades, new Item(1, "FUEL"), new CountMap<>());
+	private long findCosts() throws IOException {
+		return findCost(new Item(1, "FUEL"), new LongCountMap<>());
 	}
 
-	private Trade getTrade(Trade[] trades, String key) {
+	private Trade getTrade(String key) {
 		return Arrays.stream(trades).filter(e -> e.output.item.equals(key)).findAny().get();
 	}
-	
-	CountMap<String> created = new CountMap<>();
-	private int findCost(Trade[] trades, Item buyingItem, CountMap<String> leftOver) {
+
+	private long findCost(Item buyingItem, LongCountMap<String> leftOver) {
 		if(buyingItem.item.equals("ORE"))
 			return buyingItem.amount;
 		else if(buyingItem.amount <= leftOver.get(buyingItem.item)) {
@@ -34,39 +38,33 @@ else if(buyingItem.amount <= leftOver.get(buyingItem.item)) {
 			return 0;
 		}
 		buyingItem.amount-=leftOver.get(buyingItem.item);
-		leftOver.put(buyingItem.item, 0);
+		leftOver.put(buyingItem.item, 0L);
 		
-		return performTrade(trades, buyingItem, leftOver);
+		return performTrade(buyingItem, leftOver);
 	}
 
-	private int performTrade(Trade[] trades, Item buyingItem, CountMap<String> leftOver) {
-		Trade fuelTrade = getTrade(trades, buyingItem.item);
-		int timesApplied = (int)Math.ceil((double)buyingItem.amount/(double)fuelTrade.output.amount);
-		int totalCost = 0;
+	private long performTrade(Item buyingItem, LongCountMap<String> 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(trades, new Item(cost.amount*timesApplied, cost.item), leftOver);
+			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 {
-		Trade[] trades = Arrays.stream(readDay(15).split(System.lineSeparator())).map(Trade::new).toArray(Trade[]::new);
-		CountMap<String> leftOver = new CountMap<>();
-		int fuel = 0;
-		
-		for(long ore = 1000000000000L, amount = ore / findCosts(); ore>0 && amount>0; ) {
-			CountMap<String> newLeftOver = new CountMap<>(leftOver);
-			int cost = findCost(trades, new Item(1, "FUEL"), newLeftOver);
-			if(cost > ore) {
-				amount /= 2;	
-			} else {
-				fuel += amount;
-				ore -= cost;
-				leftOver = newLeftOver;
-			}
+		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);
+		    }
 		}
-		return fuel;
 	}
 	
 	class Trade {
@@ -78,15 +76,10 @@ public Trade(String trade) {
 			input = Arrays.stream(inputOutput[0].split(", ")).map(Item::new).toArray(Item[]::new);
 			output = new Item(inputOutput[1]);
 		}
-
-		@Override
-		public String toString() {
-			return "Trade [input=" + Arrays.toString(input) + ", output=" + output + "]";
-		}
 	}
 	
 	class Item {
-		int amount;
+		long amount;
 		String item;
 		
 		public Item(String item) {
@@ -95,14 +88,9 @@ public Item(String item) {
 			this.item = i[1];
 		}
 
-		public Item(int i, String string) {
+		public Item(long i, String string) {
 			amount = i;
 			item = string;
 		}
-
-		@Override
-		public String toString() {
-			return "Item [amount=" + amount + ", item=" + item + "]";
-		}
 	}
 }
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<K> extends HashMap<K, Long> {
+	/**
+	 * 
+	 */
+	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<K> amountPerCloneClassSize) {
+		amountPerCloneClassSize.entrySet().stream().forEach(e -> this.increment(e.getKey(), e.getValue()));
+	}
+
+	public void incrementAll(LongCountMap<K> input) {
+		for(Entry<K, Long> i : input.entrySet()) {
+			increment(i.getKey(), i.getValue());
+		}
+	}
+}

From 7129d3ebf49cc011910a11be0a00c7f5d084c86b Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 14 Dec 2019 22:48:18 +0100
Subject: [PATCH 077/120] Final day 14 refactor

---
 .../sbaars/adventofcode2019/days/Day14.java   | 12 ++++------
 .../sbaars/adventofcode2019/days/Day15.java   | 22 +++++++++++++++++++
 src/main/resources/day15.txt                  |  9 --------
 src/main/resources/day16.txt                  | 12 ----------
 src/main/resources/day17.txt                  |  7 ------
 5 files changed, 26 insertions(+), 36 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day15.java
 delete mode 100644 src/main/resources/day16.txt
 delete mode 100644 src/main/resources/day17.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
index 2154a2bf..5ededc12 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day14.java
@@ -19,10 +19,6 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public Object part1() throws IOException {
-		return findCosts();
-	}
-
-	private long findCosts() throws IOException {
 		return findCost(new Item(1, "FUEL"), new LongCountMap<>());
 	}
 
@@ -68,8 +64,8 @@ public Object part2() throws IOException {
 	}
 	
 	class Trade {
-		final Item[] input;
-		final Item output;
+		private final Item[] input;
+		private final Item output;
 		
 		public Trade(String trade) {
 			String[] inputOutput = trade.split(" => ");
@@ -79,8 +75,8 @@ public Trade(String trade) {
 	}
 	
 	class Item {
-		long amount;
-		String item;
+		private long amount;
+		private final String item;
 		
 		public Item(String item) {
 			String[] i = item.split(" ");
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..7fb97e0a
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -0,0 +1,22 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+public class Day15 implements Day {
+
+	public static void main(String[] args) throws IOException {
+		new Day15().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		return 0;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		return 0;
+	}
+}
diff --git a/src/main/resources/day15.txt b/src/main/resources/day15.txt
index fe064792..e69de29b 100644
--- a/src/main/resources/day15.txt
+++ b/src/main/resources/day15.txt
@@ -1,9 +0,0 @@
-157 ORE => 5 NZVS
-165 ORE => 6 DCFZ
-44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
-12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
-179 ORE => 7 PSHF
-177 ORE => 5 HKGWZ
-7 DCFZ, 7 PSHF => 2 XJWVT
-165 ORE => 2 GPVTF
-3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT
\ No newline at end of file
diff --git a/src/main/resources/day16.txt b/src/main/resources/day16.txt
deleted file mode 100644
index 7c1333b1..00000000
--- a/src/main/resources/day16.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
-17 NVRVD, 3 JNWZP => 8 VPVL
-53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
-22 VJHF, 37 MNCFX => 5 FWMGM
-139 ORE => 4 NVRVD
-144 ORE => 7 JNWZP
-5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC
-5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV
-145 ORE => 6 MNCFX
-1 NVRVD => 8 CXFTF
-1 VJHF, 6 MNCFX => 4 RFSQX
-176 ORE => 6 VJHF
\ No newline at end of file
diff --git a/src/main/resources/day17.txt b/src/main/resources/day17.txt
deleted file mode 100644
index 80a5907e..00000000
--- a/src/main/resources/day17.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-9 ORE => 2 A
-8 ORE => 3 B
-7 ORE => 5 C
-3 A, 4 B => 1 AB
-5 B, 7 C => 1 BC
-4 C, 1 A => 1 CA
-2 AB, 3 BC, 4 CA => 1 FUEL
\ No newline at end of file

From ab80b393ea500fe130fb12f50ad271f30f3dec13 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 15 Dec 2019 13:49:35 +0100
Subject: [PATCH 078/120] Upgrade Intcode Computer

---
 .../sbaars/adventofcode2019/days/Day11.java   | 10 +++----
 .../sbaars/adventofcode2019/days/Day13.java   | 18 ++++++-------
 .../sbaars/adventofcode2019/days/Day7.java    | 18 ++++++-------
 .../intcode/IntcodeComputer.java              | 27 ++++++++++---------
 4 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index d5a12a94..7098113b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -33,18 +33,18 @@ private Object robotWalk(boolean startWhite) throws IOException {
 			whitePlaces.add(currentLocation);
 		while(true) {
 			c.setInput(whitePlaces.contains(currentLocation) ? 1 : 0);
-			int paintColor = c.runInt();
+			long paintColor = c.run();
 			if(paintColor == IntcodeComputer.STOP_CODE)
 				break;
-			int turn = c.runInt();
+			long turn = c.run();
 			paintedOnce.add(currentLocation);
-			if(paintColor == 1) {
+			if(paintColor == 1L) {
 				whitePlaces.add(currentLocation);
-			} else if(paintColor == 0) {
+			} else if(paintColor == 0L) {
 				whitePlaces.remove(currentLocation);
 			}
 			
-			dir = turn(dir, turn == 1);
+			dir = turn(dir, turn == 1L);
 			currentLocation = move(currentLocation, dir);
 		}
 		return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day13.java b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
index d3b4fea7..dc288e2b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day13.java
@@ -20,12 +20,12 @@ public Object part1() throws IOException {
 		IntcodeComputer cp = new IntcodeComputer(13);
 		Set<Point> n = new HashSet<Point>();
 		while(true) {
-			int x = cp.runInt();
+			long x = cp.run();
 			if(x == IntcodeComputer.STOP_CODE) return n.size();
-			int y = cp.runInt();
-			int tile = cp.runInt();
+			long y = cp.run();
+			long tile = cp.run();
 			if(tile == 2)
-				n.add(new Point(x,y));
+				n.add(new Point(Math.toIntExact(x), Math.toIntExact(y)));
 		}
 	}
 	
@@ -37,12 +37,12 @@ public Object part2() throws IOException {
 		int score = 0;
 		AtomicInteger paddlePos = new AtomicInteger(), ballPos = new AtomicInteger();
 		while(true) {
-			int x = cp.runInt();
+			long x = cp.run();
 			if(x == IntcodeComputer.STOP_CODE)
 				return score;
-			int y = cp.runInt();
-			int tile = cp.runInt();
-			score = simulateField(cp, field, score, paddlePos, ballPos, x, y, tile);
+			long y = cp.run();
+			long tile = cp.run();
+			score = simulateField(cp, field, score, paddlePos, ballPos, Math.toIntExact(x), Math.toIntExact(y), Math.toIntExact(tile));
 		}
 	}
 
@@ -52,7 +52,7 @@ private int simulateField(IntcodeComputer cp, int[][] field, int score, AtomicIn
 		else {
 			field[y][x] = tile;
 			if (tile == 3) {
-				paddlePos.set(x);;
+				paddlePos.set(x);
 			} else if (tile == 4) {
 				ballPos.set(x);
 				cp.setInput(provideInput(paddlePos, ballPos));
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index a1af8316..46c0248c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -17,30 +17,30 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
-		List<Integer> results = new ArrayList<>();
+		List<Long> results = new ArrayList<>();
 		for(List<Integer> perm : permutations) {
-			int lastVal = 0;
+			long lastVal = 0;
 			for(Integer i : perm)
-				lastVal = new IntcodeComputer(7, i, lastVal).runInt();
+				lastVal = new IntcodeComputer(7, i, lastVal).run();
 			results.add(lastVal);
 
 		}
-		return results.stream().mapToInt(e -> e).max().getAsInt();
+		return results.stream().mapToLong(e -> e).max().getAsLong();
 	}
 
 	@Override
 	public Object part2() throws IOException {
 		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
-		List<Integer> results = new ArrayList<>();
+		List<Long> results = new ArrayList<>();
 		perms: for(List<Integer> shuffle : permutations) {
 			IntcodeComputer[] computers = new IntcodeComputer[5];
 			for(int i = 0; i<computers.length; i++) computers[i] = new IntcodeComputer(7, shuffle.get(i));
-			int lastVal = 0;
+			long lastVal = 0;
 			while(true) {
 				for(IntcodeComputer c : computers) {
 					c.addInput(lastVal);
-					int thruster = lastVal;
-					lastVal = c.runInt();
+					long thruster = lastVal;
+					lastVal = c.run();
 					if(lastVal == IntcodeComputer.STOP_CODE) {
 						results.add(thruster);
 						continue perms;
@@ -49,7 +49,7 @@ public Object part2() throws IOException {
 			}
 
 		}
-		return results.stream().mapToInt(e -> e).max().getAsInt();
+		return results.stream().mapToLong(e -> e).max().getAsLong();
 	}
 
 	public <E> List<List<E>> generatePerm(List<E> original) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index a1e45299..d484e707 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -12,13 +12,13 @@
 public class IntcodeComputer implements DoesFileOperations {
 	private long[] program;
 	private int instructionCounter = 0;
-	private final Queue<Integer> input = new ArrayDeque<>(2);
-	private int lastInput;
+	private final Queue<Long> 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 int STOP_CODE = Integer.MIN_VALUE+1;
+	public static final long STOP_CODE = Long.MIN_VALUE+1;
 	
-	public IntcodeComputer(int day, int...input) throws IOException {
+	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 enlange memory, should be refactored.
 		setInput(input);
@@ -28,6 +28,11 @@ public IntcodeComputer(int day, int...input) throws IOException {
 		}
 	}
 	
+	public long run(long input) {
+		setInput(input);
+		return run();
+	}
+	
 	public long run() {
 		long result;
 		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == Integer.MIN_VALUE);
@@ -59,14 +64,14 @@ private void transformParameters(int[] method, long[] args, int instruction) {
 		}
 	}
 	
-	private int readInput() {
+	private long readInput() {
 		if(input.isEmpty())
 			return lastInput;
 		lastInput = input.poll();
 		return lastInput;
 	}
 	
-	public boolean addInput(int num) {
+	public boolean addInput(long num) {
 		return input.add(num);
 	}
 	
@@ -74,7 +79,7 @@ public long firstElement() {
 		return program[0];
 	}
 	
-	public boolean setInput(int...input) {
+	public boolean setInput(long...input) {
 		this.input.clear();
 		return this.input.addAll(Arrays.stream(input).boxed().collect(Collectors.toList()));
 	}
@@ -94,7 +99,7 @@ private long executeInstruction(long[] args, int instruction) {
 			case 99: return STOP_CODE;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
-		return Integer.MIN_VALUE;
+		return Long.MIN_VALUE;
 	}
 	
 	private long parseComplexInstruction(int instruction) {
@@ -136,11 +141,7 @@ private int nParams(int instruction) {
 			else throw new IllegalStateException("Something went wrong! "+instruction);
 		}
 	}
-
-	public int runInt() {
-		return Math.toIntExact(run());
-	}
-
+	
 	public void setElement(int i, long j) {
 		program[i] = j;
 	}

From 41f686caba37ccba1d8a498fa986db7852055e83 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 15 Dec 2019 13:49:55 +0100
Subject: [PATCH 079/120] Path finding classes for day 15

---
 .../adventofcode2019/pathfinding/Grid2d.java  | 127 ++++++++++++++++++
 .../adventofcode2019/pathfinding/Node.java    |  40 ++++++
 .../pathfinding/PathFinding.java              |  86 ++++++++++++
 3 files changed, 253 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/pathfinding/Node.java
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java

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..bc269d9d
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
@@ -0,0 +1,127 @@
+package com.sbaars.adventofcode2019.pathfinding;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 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 double[][] 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<MapNode> {
+		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<MapNode> getNeighbours() {
+			Set<MapNode> neighbours = new HashSet<MapNode>();
+
+			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] == 1) {
+						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;
+		}
+
+		private Grid2d getOuterType() {
+			return Grid2d.this;
+		}
+
+	}
+
+	public Grid2d(double[][] map, boolean allowDiagonal) {
+		this.map = map;
+		this.allowDiagonal = allowDiagonal;
+	}
+
+	public List<MapNode> findPath(int xStart, int yStart, int xGoal, int yGoal) {
+		return PathFinding.doAStar(new MapNode(xStart, yStart), new MapNode(
+				xGoal, yGoal));
+	}
+
+}
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 <T>
+ *            Actual type of the node
+ */
+public interface Node<T> {
+	/**
+	 * 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<T> 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..51ec92d5
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
@@ -0,0 +1,86 @@
+package com.sbaars.adventofcode2019.pathfinding;
+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 <T extends Node<T>> List<T> doAStar(T start, T goal) {
+		Set<T> closed = new HashSet<T>();
+		Map<T, T> fromMap = new HashMap<T, T>();
+		List<T> route = new LinkedList<T>();
+		Map<T, Double> gScore = new HashMap<T, Double>();
+		final Map<T, Double> fScore = new HashMap<T, Double>();
+		PriorityQueue<T> open = new PriorityQueue<T>(11, new Comparator<T>() {
+
+			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 null;
+	}
+
+}

From 14b8075568576087d9b7d8a4b9d46ea37d6be9f3 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 15 Dec 2019 14:10:01 +0100
Subject: [PATCH 080/120] Direction refactor

---
 .../adventofcode2019/common/Direction.java    | 22 ++++++++++++++++
 .../sbaars/adventofcode2019/days/Day11.java   | 25 ++++++-------------
 .../sbaars/adventofcode2019/days/Day3.java    | 22 +++++-----------
 3 files changed, 36 insertions(+), 33 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/common/Direction.java

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..dde18371
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -0,0 +1,22 @@
+package com.sbaars.adventofcode2019.common;
+
+import java.util.Arrays;
+
+public enum Direction {
+	NORTH, EAST, SOUTH, WEST;
+	
+	public char directionCode() {
+		return name().charAt(0);
+	}
+	
+	public static Direction getByDirCode(char code) {
+		return Arrays.stream(values()).filter(e -> e.directionCode() == 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];
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 7098113b..f466e0cd 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -10,9 +10,9 @@
 import com.sbaars.adventofcode2019.common.ProcessesImages;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
 
+import com.sbaars.adventofcode2019.common.Direction;
+
 public class Day11 implements Day, ProcessesImages {
-	
-	enum Direction { UP, RIGHT, DOWN, LEFT }
 
 	public static void main(String[] args) throws IOException {
 		new Day11().printParts();
@@ -26,7 +26,7 @@ public Object part1() throws IOException {
 	private Object robotWalk(boolean startWhite) throws IOException {
 		IntcodeComputer c = new IntcodeComputer(11);
 		Point currentLocation = new Point(0,0);
-		Direction dir = Direction.UP;
+		Direction dir = Direction.NORTH;
 		final Set<Point> paintedOnce = new HashSet<>();
 		final Set<Point> whitePlaces = new HashSet<>();
 		if(startWhite)
@@ -44,7 +44,7 @@ private Object robotWalk(boolean startWhite) throws IOException {
 				whitePlaces.remove(currentLocation);
 			}
 			
-			dir = turn(dir, turn == 1L);
+			dir = dir.turn(turn == 1L);
 			currentLocation = move(currentLocation, dir);
 		}
 		return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
@@ -61,22 +61,13 @@ private OCR constructImage(Set<Point> whitePlaces) {
 			places[p.y][p.x] = 1;
 		return new OCR(createAsciiArray(places));
 	}
-
-	public Direction turn(Direction dir, boolean right) {
-		int cur = dir.ordinal() + (right ? 1 : -1);
-		if(cur == Direction.values().length)
-			cur = 0;
-		else if(cur == -1)
-			cur = 3;
-		return Direction.values()[cur];
-	}
 	
 	private Point move(Point currentLocation, Direction dir2) {
 		switch (dir2) {
-			case UP: return new Point(currentLocation.x, currentLocation.y-1);
-			case DOWN: return new Point(currentLocation.x, currentLocation.y+1);
-			case RIGHT: return new Point(currentLocation.x+1, currentLocation.y);
-			case LEFT: return new Point(currentLocation.x-1, currentLocation.y);
+			case NORTH: return new Point(currentLocation.x, currentLocation.y-1);
+			case SOUTH: return new Point(currentLocation.x, currentLocation.y+1);
+			case EAST: return new Point(currentLocation.x+1, currentLocation.y);
+			case WEST: return new Point(currentLocation.x-1, currentLocation.y);
 		}
 		return null;
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 55a094b6..6a8c22e2 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -6,6 +6,8 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import com.sbaars.adventofcode2019.common.Direction;
+
 import com.sbaars.adventofcode2019.common.Day;
 
 public class Day3 implements Day
@@ -41,10 +43,10 @@ private Set<Step> calculateDistance(Walk[] walks1, Set<Step> walkedLocations, bo
 		for(Walk walk : walks1) {
 			for(;walk.distance>0;walk.distance--) {
 				switch(walk.dir) {
-					case UP: y++; break;
-					case DOWN: y--; break;
-					case LEFT: x--; break;
-					case RIGHT: x++; break;
+					case NORTH: y++; break;
+					case SOUTH: y--; break;
+					case WEST: x--; break;
+					case EAST: x++; break;
 				}
 				performStep(walkedLocations, collect, intersectingLocations, x, y, steps);
 				steps++;
@@ -113,16 +115,4 @@ public void combine(Step step) {
 			}
 		}
 	}
-	
-	enum Direction {
-		UP, DOWN, LEFT, RIGHT;
-		
-		public char directionCode() {
-			return name().charAt(0);
-		}
-		
-		public static Direction getByDirCode(char code) {
-			return Arrays.stream(values()).filter(e -> e.directionCode() == code).findAny().get();
-		}
-	}
 }

From 732f7a7b07a6a6ea6761fec1900f050307ab2ba6 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 15 Dec 2019 14:15:18 +0100
Subject: [PATCH 081/120] Further direction refactoring

---
 .../adventofcode2019/common/Direction.java    | 19 ++++++++++++++++++-
 .../sbaars/adventofcode2019/days/Day11.java   | 12 +-----------
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
index dde18371..b81ac8bc 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -1,9 +1,16 @@
 package com.sbaars.adventofcode2019.common;
 
+import java.awt.Point;
 import java.util.Arrays;
 
 public enum Direction {
-	NORTH, EAST, SOUTH, WEST;
+	NORTH(1), EAST(4), SOUTH(2), WEST(3);
+	
+	public final int num;
+	
+	private Direction(int num) {
+		this.num = num;
+	}
 	
 	public char directionCode() {
 		return name().charAt(0);
@@ -19,4 +26,14 @@ public Direction turn(boolean right) {
 		else if(cur == -1) cur = 3;
 		return Direction.values()[cur];
 	}
+	
+	public Point move(Point currentLocation) {
+		switch (this) {
+			case NORTH: return new Point(currentLocation.x, currentLocation.y+1);
+			case SOUTH: return new Point(currentLocation.x, currentLocation.y-1);
+			case EAST: return new Point(currentLocation.x+1, currentLocation.y);
+			case WEST: return new Point(currentLocation.x-1, currentLocation.y);
+		}
+		return null;
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index f466e0cd..0ef8815a 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -45,7 +45,7 @@ private Object robotWalk(boolean startWhite) throws IOException {
 			}
 			
 			dir = dir.turn(turn == 1L);
-			currentLocation = move(currentLocation, dir);
+			currentLocation = dir.move(currentLocation);
 		}
 		return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
 	}
@@ -61,16 +61,6 @@ private OCR constructImage(Set<Point> whitePlaces) {
 			places[p.y][p.x] = 1;
 		return new OCR(createAsciiArray(places));
 	}
-	
-	private Point move(Point currentLocation, Direction dir2) {
-		switch (dir2) {
-			case NORTH: return new Point(currentLocation.x, currentLocation.y-1);
-			case SOUTH: return new Point(currentLocation.x, currentLocation.y+1);
-			case EAST: return new Point(currentLocation.x+1, currentLocation.y);
-			case WEST: return new Point(currentLocation.x-1, currentLocation.y);
-		}
-		return null;
-	}
 
 	@Override
 	public Object part2() throws IOException {

From 0ad2b1be7eee62585fb9741e51a2411c57cbfba1 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 15 Dec 2019 18:04:26 +0100
Subject: [PATCH 082/120] Day 15: Stub

---
 .../com/sbaars/adventofcode2019/days/Day15.java | 17 ++++++++++++++++-
 .../adventofcode2019/pathfinding/Example.java   | 16 ++++++++++++++++
 src/main/resources/day15.txt                    |  1 +
 3 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
index 7fb97e0a..f5a92c81 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -1,8 +1,14 @@
 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;
 
 public class Day15 implements Day {
 
@@ -12,7 +18,16 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public Object part1() throws IOException {
-		return 0;
+		IntcodeComputer ic = new IntcodeComputer(15);
+		List<Point> walls = new ArrayList<>();
+		Point pos = new Point(50,50);
+		int[][] grid = new int[100][100];
+		for(int[] row : grid) Arrays.fill(row, -1);
+		grid[pos.y][pos.x] = 0;
+		Direction dir  = Direction.NORTH;
+		while(true) {
+			ic.run();
+		}
 	}
 	
 	@Override
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
new file mode 100644
index 00000000..3709f4cb
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
@@ -0,0 +1,16 @@
+package com.sbaars.adventofcode2019.pathfinding;
+
+public class Example {
+	public Example() {
+		double[][] map = { { 0, 1, 0, 0, 0 }, 
+							{ 0, 0, 0, 1, 0 }, 
+							{ 1, 1, 1, 1, 0} };
+		Grid2d map2d = new Grid2d(map, false);
+		System.out.println(map2d.findPath(0, 0, 4, 2));
+	}
+
+	public static void main(String[] args) {
+		new Example();
+	}
+
+}
diff --git a/src/main/resources/day15.txt b/src/main/resources/day15.txt
index e69de29b..0af98421 100644
--- a/src/main/resources/day15.txt
+++ 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

From 64d790da75a73c033aa4df49444e8a7482656fe9 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 16 Dec 2019 07:23:27 +0100
Subject: [PATCH 083/120] Day 16

---
 .../sbaars/adventofcode2019/days/Day16.java   | 154 ++++++++++++++++++
 src/main/resources/day16.txt                  |   1 +
 src/main/resources/day17.txt                  |   1 +
 src/main/resources/day18.txt                  |   1 +
 4 files changed, 157 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day16.java
 create mode 100644 src/main/resources/day16.txt
 create mode 100644 src/main/resources/day17.txt
 create mode 100644 src/main/resources/day18.txt

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..e2f9c3c8
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
@@ -0,0 +1,154 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.util.CountMap;
+
+public class Day16 implements Day {
+	
+	int targetPos = 5977341;
+
+	public static void main(String[] args) throws IOException {
+		new Day16().part2();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		int[] nums = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
+		//System.out.println(Arrays.toString(nums));
+		int[] pattern = {0, 1, 0, -1};
+		for(int phase = 0; phase<100; phase++) {
+		int[] newNums = new int[nums.length];
+		int timesEachElement = 1;
+		for(int j = 0; j<nums.length; j++) {
+			int[] sumArray = new int[nums.length];
+	 		for(int i = 0, patternIndex = 0, elementTimes = 1; i<nums.length; i++) {
+	 			if(elementTimes == timesEachElement) {
+	 				patternIndex++;
+	 				elementTimes = 0;
+	 				if(patternIndex == pattern.length)
+						patternIndex=0;
+	 			}
+	 			
+	 			sumArray[i] = nums[i] * pattern[patternIndex];
+	 			//System.out.print(nums[i] +"*" +pattern[patternIndex]+" ");
+	 			
+	 			elementTimes++;
+			}
+	 		//System.out.println();
+	 		newNums[j] = lastDigit(Arrays.stream(sumArray).sum());
+	 		timesEachElement++;
+		}
+		//System.out.println(arrayToInt(newNums));
+		System.out.println(Arrays.toString(newNums));
+		nums = newNums;
+		}
+		return 0;
+	}
+	
+	int arrayToInt(int[] arr)
+	{
+	    int result = 0;
+
+	    //iterate backwards through the array so we start with least significant digits
+	    for (int n = arr.length - 1, i = 1; n >= 0; n --, i *= 10) 
+	    {
+	         result += Math.abs(arr[n]) * i;
+	    }
+
+	    if (arr[0] < 0) //if there's a negative sign in the beginning, flip the sign
+	    {
+	        result = - result;
+	    }
+
+	    return result;
+	}
+
+	
+	private int lastDigit(int number) {
+		return Math.abs(number) % 10;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		int[] actNums = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
+		
+		int totalTimes = 10000;
+		//System.out.println(nums.length);
+		//int[] nums = repeat(actNums, 10000);
+		//System.out.println(Arrays.toString(nums));
+		int[] pattern = {0, 1, 0, -1};
+		for(int phase = 0; phase<100; phase++) {
+			System.out.println("Phase "+phase);
+		int[] newNums = new int[totalTimes];
+		int timesEachElement = 1;
+		for(int j = 0; j<totalTimes; j++) {
+			//System.out.println("Num "+j);
+			//int[] sumArray = new int[nums.length];
+			Map<Point, int[]> numsForIndices = new HashMap<>();
+			CountMap<Point> timesEachPoint = new CountMap<>();
+			for(int o = 0; o<totalTimes; o+=actNums.length) {
+				int patternIndex = (o / timesEachElement) % pattern.length;
+				int elementTimes = o % timesEachElement + 1;
+				//System.out.println(patternIndex+", "+elementTimes);
+				Point p = new Point(patternIndex, elementTimes);
+				if(numsForIndices.containsKey(p)) {
+					//int[] arr = numsForIndices.get(p);
+					//System.arraycopy(sumArray, o, arr, 0, arr.length);
+					timesEachPoint.increment(p);
+				} else {
+					int[] res = new int[actNums.length];
+					for(int i = 0; i<actNums.length; i++) {
+			 			if(elementTimes == timesEachElement) {
+			 				patternIndex++;
+			 				elementTimes = 0;
+			 				if(patternIndex == pattern.length)
+								patternIndex=0;
+			 			}
+			 			
+			 			res[i] = actNums[i] * pattern[patternIndex];
+			 			//System.out.print(nums[i] +"*" +pattern[patternIndex]+" ");
+			 			
+			 			elementTimes++;
+					}
+					//System.arraycopy(sumArray, o, res, 0, res.length);
+					numsForIndices.put(p, res);
+					timesEachPoint.increment(p);
+				}
+			}
+	 		//System.out.println();
+			int sum = 0;
+			for(Entry<Point, int[]> arr : numsForIndices.entrySet()) {
+				sum+=Arrays.stream(arr.getValue()).sum() * timesEachPoint.get(arr.getKey());
+			}
+	 		newNums[j] = lastDigit(sum);
+	 		timesEachElement++;
+		}
+		//System.out.println(arrayToInt(newNums));
+		//System.out.println(Arrays.toString(newNums));
+		if(phase == 99) {
+			for(int i = 5977341; i<5977341+8; i++) {
+				System.out.println(newNums[i]);
+			}
+		}
+		actNums = newNums;
+		}
+		return 0;
+	}
+	
+	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/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..e9a9ea1f
--- /dev/null
+++ b/src/main/resources/day17.txt
@@ -0,0 +1 @@
+12345678
\ 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..1a27961e
--- /dev/null
+++ b/src/main/resources/day18.txt
@@ -0,0 +1 @@
+80871224585914546619083218645595
\ No newline at end of file

From 5cc71d10d4fdd2126ce929b5836b145608c80224 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 16 Dec 2019 08:26:42 +0100
Subject: [PATCH 084/120] Improved and refactored algorithm

---
 .../sbaars/adventofcode2019/days/Day16.java   | 58 ++++++++++++-------
 1 file changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day16.java b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
index e2f9c3c8..0fed65a0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
@@ -1,14 +1,9 @@
 package com.sbaars.adventofcode2019.days;
 
-import java.awt.Point;
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.util.CountMap;
 
 public class Day16 implements Day {
 	
@@ -77,23 +72,42 @@ private int lastDigit(int number) {
 	
 	@Override
 	public Object part2() throws IOException {
-		int[] actNums = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
-		
-		int totalTimes = 10000;
+		int[] nums = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
+		nums = repeat(nums, 10000);
 		//System.out.println(nums.length);
 		//int[] nums = repeat(actNums, 10000);
 		//System.out.println(Arrays.toString(nums));
 		int[] pattern = {0, 1, 0, -1};
+		
+		int[] res = new int[nums.length];
 		for(int phase = 0; phase<100; phase++) {
 			System.out.println("Phase "+phase);
-		int[] newNums = new int[totalTimes];
-		int timesEachElement = 1;
-		for(int j = 0; j<totalTimes; j++) {
+			
+			int[] newNums = new int[nums.length+1];
+			for(int i=0;i<nums.length;i++) {
+				newNums[i+1]=newNums[i]+nums[i];
+			}
+		
+			for(int i = 0; i<nums.length; i++) {
+				int sum = 0, loc = 0;
+				for(int j=0; true;j++) {
+					int k=((j+1)*(i+1))-1;
+					sum += (newNums[Math.min(k, res.length)] - newNums[loc]) * pattern[j%4];
+					if(k >= res.length) break;
+					loc=k;
+				}
+				res[i]=Math.abs(sum)%10;
+			}
+			
+			System.arraycopy(res, 0, nums, 0, res.length);
+			//nums=Arrays.copyOf(res,res.length);
+		//int timesEachElement = 1;
+		//for(int j = 0; j<totalTimes; j++) {
 			//System.out.println("Num "+j);
 			//int[] sumArray = new int[nums.length];
-			Map<Point, int[]> numsForIndices = new HashMap<>();
-			CountMap<Point> timesEachPoint = new CountMap<>();
-			for(int o = 0; o<totalTimes; o+=actNums.length) {
+			//Map<Point, int[]> numsForIndices = new HashMap<>();
+			//CountMap<Point> timesEachPoint = new CountMap<>();
+			/*for(int o = 0; o<totalTimes; o+=actNums.length) {
 				int patternIndex = (o / timesEachElement) % pattern.length;
 				int elementTimes = o % timesEachElement + 1;
 				//System.out.println(patternIndex+", "+elementTimes);
@@ -121,24 +135,24 @@ public Object part2() throws IOException {
 					numsForIndices.put(p, res);
 					timesEachPoint.increment(p);
 				}
-			}
+			}*/
 	 		//System.out.println();
-			int sum = 0;
+			/*int sum = 0;
 			for(Entry<Point, int[]> arr : numsForIndices.entrySet()) {
 				sum+=Arrays.stream(arr.getValue()).sum() * timesEachPoint.get(arr.getKey());
 			}
 	 		newNums[j] = lastDigit(sum);
-	 		timesEachElement++;
+	 		timesEachElement++;*/
 		}
 		//System.out.println(arrayToInt(newNums));
 		//System.out.println(Arrays.toString(newNums));
-		if(phase == 99) {
+		//if(phase == 99) {
 			for(int i = 5977341; i<5977341+8; i++) {
-				System.out.println(newNums[i]);
+				System.out.println(res[i]);
 			}
-		}
-		actNums = newNums;
-		}
+		//}
+		//actNums = newNums;
+		//}
 		return 0;
 	}
 	

From aa4169cd163d2f4d49a77b5dc62c73b6a3458a5a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 16 Dec 2019 19:08:31 +0100
Subject: [PATCH 085/120] Runbot

---
 .../adventofcode2019/common/Direction.java    | 20 ++++-
 .../sbaars/adventofcode2019/days/Day15.java   | 74 +++++++++++++++++--
 .../adventofcode2019/pathfinding/Example.java |  6 +-
 .../adventofcode2019/pathfinding/Grid2d.java  | 15 ++--
 src/main/resources/day17.txt                  |  1 -
 src/main/resources/day18.txt                  |  1 -
 6 files changed, 100 insertions(+), 17 deletions(-)
 delete mode 100644 src/main/resources/day17.txt
 delete mode 100644 src/main/resources/day18.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
index b81ac8bc..42d1e0a5 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -34,6 +34,24 @@ public Point move(Point currentLocation) {
 			case EAST: return new Point(currentLocation.x+1, currentLocation.y);
 			case WEST: return new Point(currentLocation.x-1, currentLocation.y);
 		}
-		return null;
+		throw new IllegalStateException("Non-existent Direction: "+this);
+	}
+
+	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);
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
index f5a92c81..04ed4f75 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -9,8 +9,16 @@
 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 {
+	
+	private static final int UNEXPLORED = -1;
+	private static final int WALL = 0;
+	private static final int PATH = 1;
+	private static final int FINISH = 2;
+	private static final int BOARD_SIZE = 100;
+	private static final Point START_POINT = new Point(BOARD_SIZE/2,BOARD_SIZE/2);
 
 	public static void main(String[] args) throws IOException {
 		new Day15().printParts();
@@ -19,14 +27,68 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		IntcodeComputer ic = new IntcodeComputer(15);
-		List<Point> walls = new ArrayList<>();
-		Point pos = new Point(50,50);
-		int[][] grid = new int[100][100];
-		for(int[] row : grid) Arrays.fill(row, -1);
+		Point pos = START_POINT;
+		int[][] grid = new int[BOARD_SIZE][BOARD_SIZE];
+		for(int[] row : grid) Arrays.fill(row, UNEXPLORED);
 		grid[pos.y][pos.x] = 0;
-		Direction dir  = Direction.NORTH;
 		while(true) {
-			ic.run();
+			explore(grid, pos, ic);
+			pos = moveToUnexploredPlace(grid, pos, ic);
+			if(pos == null) {
+				Grid2d map2d = new Grid2d(grid, false);
+				System.out.println(Arrays.deepToString(grid));
+				return map2d.findPath(START_POINT, findPos(grid, FINISH).get(0)).length;
+			}
+		}
+	}
+	
+	private Point moveToUnexploredPlace(int[][] grid, Point pos, IntcodeComputer ic) {
+		List<Point> corridorSpaces = findPos(grid, PATH);
+		for(Point p : corridorSpaces) {
+			if(hasAdjecent(grid, p, UNEXPLORED)) {
+				Grid2d map2d = new Grid2d(grid, false);
+				Point[] route = map2d.findPath(START_POINT, findPos(grid, FINISH).get(0));
+				traverseRoute(ic, pos, route);
+				return p;
+			}
+		}
+		return null;
+	}
+	
+	private void traverseRoute(IntcodeComputer ic, Point pos, Point[] route) {
+		for(Point p : route) {
+			ic.run(Direction.getByMove(pos, p).num);
+		}
+	}
+
+	private boolean hasAdjecent(int[][] grid, 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<Point> findPos(int[][] grid, int tile) {
+		List<Point> positions = new ArrayList<>();
+		for(int y = 0; y<grid.length; y++) {
+			for(int x = 0; x<grid[y].length; x++) {
+				if(grid[y][x] == tile)
+					positions.add(new Point(x, y));
+			}
+		}
+		return positions;
+	}
+
+	private void explore(int[][] grid, Point pos, IntcodeComputer ic) {
+		Direction dir  = Direction.NORTH;
+		for(int i = 0; i<4;i++) {
+			Point move = dir.move(pos);
+			if(grid[move.y][move.x] == UNEXPLORED) {
+				long run = ic.run(dir.num);
+				System.out.println(run);
+				grid[move.y][move.x] = Math.toIntExact(run);
+				if(grid[move.y][move.x] != WALL) {
+					ic.run(dir.opposite().num); // Move back
+				}
+			}
+			dir = dir.turn(true);
 		}
 	}
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
index 3709f4cb..4d167f0b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
@@ -1,12 +1,14 @@
 package com.sbaars.adventofcode2019.pathfinding;
 
+import java.awt.Point;
+
 public class Example {
 	public Example() {
-		double[][] map = { { 0, 1, 0, 0, 0 }, 
+		int[][] map = { { 0, 1, 0, 0, 0 }, 
 							{ 0, 0, 0, 1, 0 }, 
 							{ 1, 1, 1, 1, 0} };
 		Grid2d map2d = new Grid2d(map, false);
-		System.out.println(map2d.findPath(0, 0, 4, 2));
+		System.out.println(map2d.findPath(new Point(0, 0), new Point(4, 2)));
 	}
 
 	public static void main(String[] args) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
index bc269d9d..ea2a41bf 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
@@ -1,7 +1,7 @@
 package com.sbaars.adventofcode2019.pathfinding;
 
+import java.awt.Point;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -16,7 +16,7 @@
  * 
  */
 public class Grid2d {
-	private final double[][] map;
+	private final int[][] map;
 	private final boolean allowDiagonal;
 
 	/**
@@ -107,6 +107,10 @@ public boolean equals(Object obj) {
 				return false;
 			return true;
 		}
+		
+		public Point toPoint() {
+			return new Point(x, y);
+		}
 
 		private Grid2d getOuterType() {
 			return Grid2d.this;
@@ -114,14 +118,13 @@ private Grid2d getOuterType() {
 
 	}
 
-	public Grid2d(double[][] map, boolean allowDiagonal) {
+	public Grid2d(int[][] map, boolean allowDiagonal) {
 		this.map = map;
 		this.allowDiagonal = allowDiagonal;
 	}
 
-	public List<MapNode> findPath(int xStart, int yStart, int xGoal, int yGoal) {
-		return PathFinding.doAStar(new MapNode(xStart, yStart), new MapNode(
-				xGoal, yGoal));
+	public Point[] findPath(Point start, Point end) {
+		return PathFinding.doAStar(new MapNode(start.x, start.y), new MapNode(end.x, end.y)).stream().map(MapNode::toPoint).toArray(Point[]::new);
 	}
 
 }
diff --git a/src/main/resources/day17.txt b/src/main/resources/day17.txt
deleted file mode 100644
index e9a9ea1f..00000000
--- a/src/main/resources/day17.txt
+++ /dev/null
@@ -1 +0,0 @@
-12345678
\ No newline at end of file
diff --git a/src/main/resources/day18.txt b/src/main/resources/day18.txt
deleted file mode 100644
index 1a27961e..00000000
--- a/src/main/resources/day18.txt
+++ /dev/null
@@ -1 +0,0 @@
-80871224585914546619083218645595
\ No newline at end of file

From 8690890d75669144dee8ddabb7086a20f5026cae Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 16 Dec 2019 19:11:49 +0100
Subject: [PATCH 086/120] Ignore classpath

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

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

From 1e08a6bb02da376a76703f11d2fa0b3266a432a6 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Mon, 16 Dec 2019 19:45:43 +0100
Subject: [PATCH 087/120] Stuff

---
 .../adventofcode2019/common/Direction.java     |  4 ++--
 .../sbaars/adventofcode2019/common/OCR.java    | 14 ++++++++------
 .../sbaars/adventofcode2019/days/Day15.java    | 18 +++++++++---------
 .../intcode/IntcodeComputer.java               |  7 ++++---
 .../adventofcode2019/pathfinding/Example.java  |  2 +-
 .../adventofcode2019/pathfinding/Grid2d.java   |  8 +++++---
 .../pathfinding/PathFinding.java               |  2 +-
 .../sbaars/adventofcode2019/IntcodeTest.java   |  4 ++--
 8 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
index 42d1e0a5..2464e705 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -29,8 +29,8 @@ public Direction turn(boolean right) {
 	
 	public Point move(Point currentLocation) {
 		switch (this) {
-			case NORTH: return new Point(currentLocation.x, currentLocation.y+1);
-			case SOUTH: return new Point(currentLocation.x, currentLocation.y-1);
+			case SOUTH: return new Point(currentLocation.x, currentLocation.y+1);
+			case NORTH: return new Point(currentLocation.x, currentLocation.y-1);
 			case EAST: return new Point(currentLocation.x+1, currentLocation.y);
 			case WEST: return new Point(currentLocation.x-1, currentLocation.y);
 		}
diff --git a/src/main/java/com/sbaars/adventofcode2019/common/OCR.java b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
index 470e7c50..a75fdf1e 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
@@ -1,6 +1,7 @@
 package com.sbaars.adventofcode2019.common;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 @SuppressWarnings("preview")
@@ -29,7 +30,7 @@ public String toString() {
 				case " ██ " -> middleTwo(character);
 				case "  ██" -> 'J';
 				case "â–ˆ   " -> 'L';
-				default -> dontKnow();
+				default -> dontKnow(character);
 			});
 		}
 		return result.toString();
@@ -39,7 +40,7 @@ private char bothSides(String[] character) {
 		return switch(character[5]) {
 			case " ██ " -> 'U';
 			case "â–ˆ  â–ˆ" -> 'H';
-			default -> dontKnow();
+			default -> dontKnow(character);
 		};
 	}
 
@@ -47,11 +48,12 @@ private char middleTwo(String[] character) {
 		return switch(character[5]) {
 			case " ███" -> 'G';
 			case "â–ˆ  â–ˆ" -> 'A';
-			default -> dontKnow();
+			default -> dontKnow(character);
 		};
 	}
 
-	private char dontKnow() {
+	private char dontKnow(String[] character) {
+		Arrays.stream(character).forEach(System.out::println);
 		throw new IllegalArgumentException("I don't know your character yet!");
 	}
 	
@@ -59,7 +61,7 @@ private char fullTop(String[] character) {
 		return switch(character[5]) {
 			case "â–ˆ   " -> 'F';
 			case "████" -> 'E';
-			default -> dontKnow();
+			default -> dontKnow(character);
 		};
 	}
 
@@ -67,7 +69,7 @@ private char threeTopLeft(String[] character) {
 		return switch(character[5]) {
 			case "â–ˆ   " -> 'P';
 			case "â–ˆ  â–ˆ" -> 'R';
-			default -> dontKnow();
+			default -> dontKnow(character);
 		};
 	}
 	
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
index 04ed4f75..668b92a0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -13,11 +13,11 @@
 
 public class Day15 implements Day {
 	
-	private static final int UNEXPLORED = -1;
+	private static final int UNEXPLORED = 3;
 	private static final int WALL = 0;
 	private static final int PATH = 1;
 	private static final int FINISH = 2;
-	private static final int BOARD_SIZE = 100;
+	private static final int BOARD_SIZE = 60;
 	private static final Point START_POINT = new Point(BOARD_SIZE/2,BOARD_SIZE/2);
 
 	public static void main(String[] args) throws IOException {
@@ -32,12 +32,14 @@ public Object part1() throws IOException {
 		for(int[] row : grid) Arrays.fill(row, UNEXPLORED);
 		grid[pos.y][pos.x] = 0;
 		while(true) {
+			System.out.println("Current pos = "+pos);
+			Arrays.stream(grid).map(e -> Arrays.toString(e)).forEach(System.out::println);
 			explore(grid, pos, ic);
 			pos = moveToUnexploredPlace(grid, pos, ic);
 			if(pos == null) {
 				Grid2d map2d = new Grid2d(grid, false);
 				System.out.println(Arrays.deepToString(grid));
-				return map2d.findPath(START_POINT, findPos(grid, FINISH).get(0)).length;
+				return map2d.findPath(START_POINT, findPos(grid, FINISH).get(0)).size();
 			}
 		}
 	}
@@ -47,15 +49,15 @@ private Point moveToUnexploredPlace(int[][] grid, Point pos, IntcodeComputer ic)
 		for(Point p : corridorSpaces) {
 			if(hasAdjecent(grid, p, UNEXPLORED)) {
 				Grid2d map2d = new Grid2d(grid, false);
-				Point[] route = map2d.findPath(START_POINT, findPos(grid, FINISH).get(0));
-				traverseRoute(ic, pos, route);
+				List<Point> route = map2d.findPath(pos, p);
+				traverseRoute(ic, pos, route.subList(1, route.size()));
 				return p;
 			}
 		}
 		return null;
 	}
 	
-	private void traverseRoute(IntcodeComputer ic, Point pos, Point[] route) {
+	private void traverseRoute(IntcodeComputer ic, Point pos, List<Point> route) {
 		for(Point p : route) {
 			ic.run(Direction.getByMove(pos, p).num);
 		}
@@ -81,9 +83,7 @@ private void explore(int[][] grid, Point pos, IntcodeComputer ic) {
 		for(int i = 0; i<4;i++) {
 			Point move = dir.move(pos);
 			if(grid[move.y][move.x] == UNEXPLORED) {
-				long run = ic.run(dir.num);
-				System.out.println(run);
-				grid[move.y][move.x] = Math.toIntExact(run);
+				grid[move.y][move.x] = Math.toIntExact(ic.run(dir.num));
 				if(grid[move.y][move.x] != WALL) {
 					ic.run(dir.opposite().num); // Move back
 				}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index d484e707..6da0b10f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -17,10 +17,11 @@ public class IntcodeComputer implements DoesFileOperations {
 	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 enlange memory, should be refactored.
+		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];
@@ -35,7 +36,7 @@ public long run(long input) {
 	
 	public long run() {
 		long result;
-		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == Integer.MIN_VALUE);
+		while((result = executeInstruction(Math.toIntExact(program[instructionCounter]))) == CONTINUE_CODE);
 		return result;
 	}
 
@@ -99,7 +100,7 @@ private long executeInstruction(long[] args, int instruction) {
 			case 99: return STOP_CODE;
 			default: throw new IllegalStateException("Something went wrong!");
 		}
-		return Long.MIN_VALUE;
+		return CONTINUE_CODE;
 	}
 	
 	private long parseComplexInstruction(int instruction) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
index 4d167f0b..a8d039b3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
@@ -8,7 +8,7 @@ public Example() {
 							{ 0, 0, 0, 1, 0 }, 
 							{ 1, 1, 1, 1, 0} };
 		Grid2d map2d = new Grid2d(map, false);
-		System.out.println(map2d.findPath(new Point(0, 0), new Point(4, 2)));
+		//System.out.println(map2d.findPath(new Point(0, 0), new Point(4, 2)));
 	}
 
 	public static void main(String[] args) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
index ea2a41bf..f93bb40c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
@@ -2,7 +2,9 @@
 
 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
@@ -63,7 +65,7 @@ public Set<MapNode> getNeighbours() {
 						continue;
 					}
 
-					if (map[j][i] == 1) {
+					if (map[j][i] < 1) {
 						continue;
 					}
 
@@ -123,8 +125,8 @@ public Grid2d(int[][] map, boolean allowDiagonal) {
 		this.allowDiagonal = allowDiagonal;
 	}
 
-	public Point[] findPath(Point start, Point end) {
-		return PathFinding.doAStar(new MapNode(start.x, start.y), new MapNode(end.x, end.y)).stream().map(MapNode::toPoint).toArray(Point[]::new);
+	public List<Point> 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/PathFinding.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
index 51ec92d5..95369ddc 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
@@ -80,7 +80,7 @@ public int compare(T nodeA, T nodeB) {
 			}
 		}
 
-		return null;
+		return route;
 	}
 
 }
diff --git a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
index 5e91b170..760ce827 100644
--- a/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
+++ b/src/test/java/com/sbaars/adventofcode2019/IntcodeTest.java
@@ -24,8 +24,8 @@ public void testDay5() throws IOException {
 	}
 	
 	public void testDay7() throws IOException {
-		Assert.assertEquals(116680, new Day7().part1());
-		Assert.assertEquals(89603079, new Day7().part2());
+		Assert.assertEquals(116680L, new Day7().part1());
+		Assert.assertEquals(89603079L, new Day7().part2());
 	}
 	
 	public void testDay9() throws IOException {

From 3add9f97c54399dd72d3cc12dc723c51593b7e0f Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 07:14:40 +0100
Subject: [PATCH 088/120] Day 17

---
 .../adventofcode2019/common/Direction.java    |  20 ++-
 .../sbaars/adventofcode2019/days/Day17.java   | 155 ++++++++++++++++++
 .../intcode/IntcodeComputer.java              |   2 +
 src/main/resources/day17.txt                  |   1 +
 4 files changed, 173 insertions(+), 5 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day17.java
 create mode 100644 src/main/resources/day17.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
index 2464e705..8f85dbe1 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -27,15 +27,19 @@ public Direction turn(boolean right) {
 		return Direction.values()[cur];
 	}
 	
-	public Point move(Point currentLocation) {
+	public Point move(Point currentLocation, int amount) {
 		switch (this) {
-			case SOUTH: return new Point(currentLocation.x, currentLocation.y+1);
-			case NORTH: return new Point(currentLocation.x, currentLocation.y-1);
-			case EAST: return new Point(currentLocation.x+1, currentLocation.y);
-			case WEST: return new Point(currentLocation.x-1, currentLocation.y);
+			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) {
@@ -54,4 +58,10 @@ public static Direction getByMove(Point from, Point to) {
 		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/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
new file mode 100644
index 00000000..87b2cd32
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -0,0 +1,155 @@
+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 java.util.stream.Collectors;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.Direction;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day17 implements Day {
+
+	public static void main(String[] args) throws IOException {
+		new Day17().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		char[][] grid = new char[48][48];
+		readDay(17);
+		IntcodeComputer ic = new IntcodeComputer(17, 1);
+		long res;
+		int x = 0, y =0;
+		int result = 0;
+		while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
+			System.out.print((char)res);
+			if(res == 10) {
+				y++;
+				x= 0;
+			} else {
+				grid[y][x] = (char)res;
+				x++;
+			}
+		}
+		for(y = 1; y<grid.length-1; y++) {
+			for(x = 1; x<grid.length-1; x++) {
+				if(hasAdjecent(grid, new Point(x,y), '#')) {
+					result+=x*y;
+				}
+			}
+		}
+		//System.out.println(y);
+		return result;
+	}
+	
+	private boolean hasAdjecent(char[][] grid, Point pos, char 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 && grid[pos.y][pos.x] == tile;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		char[][] grid = new char[48][48];
+		readDay(17);
+		IntcodeComputer ic = new IntcodeComputer(17, 2);
+		long res;
+		int x = 0, y = 0;
+		int result = 0;
+		while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
+			if(res == 10) {
+				y++;
+				x= 0;
+			} else {
+				grid[y][x] = (char)res;
+				x++;
+			}
+		}
+		//StringBuilder input = new StringBuilder();
+		Point pos = findPos(grid, '^').get(0);
+		List<Instruction> instructions = new ArrayList<>();
+		List<Point> 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;
+		}
+		System.out.println(Arrays.toString(instructions.toArray()));
+		List<String> good = new ArrayList<>();
+		int start = 0;
+		for(int i = 1; i<instructions.size(); i++) {
+			List<Instruction> is = instructions.subList(start, i);
+			if(toString(is).length()>20) {
+				good.add(toString(instructions.subList(start, i-1)));
+				start = i-1;
+			}
+		}
+		good.add(toString(instructions.subList(start, instructions.size())));
+		good.stream().forEach(System.out::println);
+		String stuff = "A,B,C,D,E,F,G,H\n" + good.stream().collect(Collectors.joining("\n"))+"\nn\n";
+		System.out.println(stuff);
+		long[] asciis = stuff.chars().mapToLong(e -> e).toArray();
+		ic = new IntcodeComputer(17, 2);
+		ic.setInput(asciis);
+		System.out.println(Arrays.toString(asciis));
+		while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
+			System.out.print((char)res);
+		}
+		return 0;
+	}
+	
+	public String toString(List<Instruction> 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<Point> 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<Point> findPos(char[][] grid, char tile) {
+		List<Point> positions = new ArrayList<>();
+		for(int y = 0; y<grid.length; y++) {
+			for(int x = 0; x<grid[y].length; x++) {
+				if(grid[y][x] == tile)
+					positions.add(new Point(x, y));
+			}
+		}
+		return positions;
+	}
+	
+	enum Dir{L,R}
+	class Instruction{
+		int amount;
+		Dir dir;
+		
+		public Instruction(int amount, Dir dir) {
+			super();
+			this.amount = amount;
+			this.dir = dir;
+		}
+
+		@Override
+		public String toString() {
+			return dir.name()+","+amount;
+		}
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 6da0b10f..77975d0c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -26,6 +26,8 @@ public IntcodeComputer(int day, long...input) throws IOException {
 		if(day == 2) {
 			program[1] = input[0];
 			program[2] = input[1];
+		} else if(day == 7) {
+			program[0] = input[0];
 		}
 	}
 	
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

From fd52fe729adb666eb0de97130bcba8dc6f10f08b Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 07:41:07 +0100
Subject: [PATCH 089/120] Oh, only three programs are allowed, then I'll
 hardcode

---
 .../com/sbaars/adventofcode2019/days/Day17.java    | 14 +++++++-------
 .../adventofcode2019/intcode/IntcodeComputer.java  |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
index 87b2cd32..325f1cbb 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -4,6 +4,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -54,10 +55,9 @@ private boolean hasAdjecent(char[][] grid, Point pos, char tile) {
 	public Object part2() throws IOException {
 		char[][] grid = new char[48][48];
 		readDay(17);
-		IntcodeComputer ic = new IntcodeComputer(17, 2);
+		IntcodeComputer ic = new IntcodeComputer(17, 1);
 		long res;
 		int x = 0, y = 0;
-		int result = 0;
 		while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
 			if(res == 10) {
 				y++;
@@ -92,18 +92,18 @@ public Object part2() throws IOException {
 		}
 		good.add(toString(instructions.subList(start, instructions.size())));
 		good.stream().forEach(System.out::println);
-		String stuff = "A,B,C,D,E,F,G,H\n" + good.stream().collect(Collectors.joining("\n"))+"\nn\n";
+		String stuff = "A,A,B,C,B,A,C,B,C,A\nL,6,R,12,L,6,L,8,L,8\nL,6,R,12,R,8,L,8\nL,4,L,4,L,6\nn\n";
 		System.out.println(stuff);
 		long[] asciis = stuff.chars().mapToLong(e -> e).toArray();
 		ic = new IntcodeComputer(17, 2);
 		ic.setInput(asciis);
 		System.out.println(Arrays.toString(asciis));
-		while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
-			System.out.print((char)res);
+		while(true) {
+			if((res = ic.run())>255L)
+				return res;
 		}
-		return 0;
 	}
-	
+
 	public String toString(List<Instruction> i) {
 		return i.stream().map(Instruction::toString).collect(Collectors.joining(","));
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 77975d0c..430f373b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -26,7 +26,7 @@ public IntcodeComputer(int day, long...input) throws IOException {
 		if(day == 2) {
 			program[1] = input[0];
 			program[2] = input[1];
-		} else if(day == 7) {
+		} else if(day == 17) {
 			program[0] = input[0];
 		}
 	}

From dad29c24a6e86db5bd4db7f10b446b71d468a60f Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 08:32:06 +0100
Subject: [PATCH 090/120] Refactor day 16

---
 .../sbaars/adventofcode2019/days/Day16.java   | 148 +++---------------
 .../sbaars/adventofcode2019/days/Day17.java   |   6 -
 2 files changed, 24 insertions(+), 130 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day16.java b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
index 0fed65a0..f2023f91 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day16.java
@@ -2,95 +2,47 @@
 
 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;
 	
-	int targetPos = 5977341;
+	public Day16() throws IOException {
+		input = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
+	}
 
 	public static void main(String[] args) throws IOException {
-		new Day16().part2();
+		new Day16().printParts();
 	}
 
 	@Override
 	public Object part1() throws IOException {
-		int[] nums = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
-		//System.out.println(Arrays.toString(nums));
-		int[] pattern = {0, 1, 0, -1};
-		for(int phase = 0; phase<100; phase++) {
-		int[] newNums = new int[nums.length];
-		int timesEachElement = 1;
-		for(int j = 0; j<nums.length; j++) {
-			int[] sumArray = new int[nums.length];
-	 		for(int i = 0, patternIndex = 0, elementTimes = 1; i<nums.length; i++) {
-	 			if(elementTimes == timesEachElement) {
-	 				patternIndex++;
-	 				elementTimes = 0;
-	 				if(patternIndex == pattern.length)
-						patternIndex=0;
-	 			}
-	 			
-	 			sumArray[i] = nums[i] * pattern[patternIndex];
-	 			//System.out.print(nums[i] +"*" +pattern[patternIndex]+" ");
-	 			
-	 			elementTimes++;
-			}
-	 		//System.out.println();
-	 		newNums[j] = lastDigit(Arrays.stream(sumArray).sum());
-	 		timesEachElement++;
-		}
-		//System.out.println(arrayToInt(newNums));
-		System.out.println(Arrays.toString(newNums));
-		nums = newNums;
-		}
-		return 0;
+		return calcRes(Arrays.copyOf(input, input.length), 0);
 	}
-	
-	int arrayToInt(int[] arr)
-	{
-	    int result = 0;
-
-	    //iterate backwards through the array so we start with least significant digits
-	    for (int n = arr.length - 1, i = 1; n >= 0; n --, i *= 10) 
-	    {
-	         result += Math.abs(arr[n]) * i;
-	    }
-
-	    if (arr[0] < 0) //if there's a negative sign in the beginning, flip the sign
-	    {
-	        result = - result;
-	    }
 
-	    return result;
-	}
-
-	
-	private int lastDigit(int number) {
-		return Math.abs(number) % 10;
-	}
-	
 	@Override
 	public Object part2() throws IOException {
-		int[] nums = readDay(16).chars().map(e -> Character.getNumericValue(e)).toArray();
-		nums = repeat(nums, 10000);
-		//System.out.println(nums.length);
-		//int[] nums = repeat(actNums, 10000);
-		//System.out.println(Arrays.toString(nums));
+		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++) {
-			System.out.println("Phase "+phase);
-			
 			int[] newNums = new int[nums.length+1];
 			for(int i=0;i<nums.length;i++) {
 				newNums[i+1]=newNums[i]+nums[i];
 			}
-		
 			for(int i = 0; i<nums.length; i++) {
 				int sum = 0, loc = 0;
 				for(int j=0; true;j++) {
+					
 					int k=((j+1)*(i+1))-1;
 					sum += (newNums[Math.min(k, res.length)] - newNums[loc]) * pattern[j%4];
 					if(k >= res.length) break;
@@ -98,71 +50,19 @@ public Object part2() throws IOException {
 				}
 				res[i]=Math.abs(sum)%10;
 			}
-			
+
 			System.arraycopy(res, 0, nums, 0, res.length);
-			//nums=Arrays.copyOf(res,res.length);
-		//int timesEachElement = 1;
-		//for(int j = 0; j<totalTimes; j++) {
-			//System.out.println("Num "+j);
-			//int[] sumArray = new int[nums.length];
-			//Map<Point, int[]> numsForIndices = new HashMap<>();
-			//CountMap<Point> timesEachPoint = new CountMap<>();
-			/*for(int o = 0; o<totalTimes; o+=actNums.length) {
-				int patternIndex = (o / timesEachElement) % pattern.length;
-				int elementTimes = o % timesEachElement + 1;
-				//System.out.println(patternIndex+", "+elementTimes);
-				Point p = new Point(patternIndex, elementTimes);
-				if(numsForIndices.containsKey(p)) {
-					//int[] arr = numsForIndices.get(p);
-					//System.arraycopy(sumArray, o, arr, 0, arr.length);
-					timesEachPoint.increment(p);
-				} else {
-					int[] res = new int[actNums.length];
-					for(int i = 0; i<actNums.length; i++) {
-			 			if(elementTimes == timesEachElement) {
-			 				patternIndex++;
-			 				elementTimes = 0;
-			 				if(patternIndex == pattern.length)
-								patternIndex=0;
-			 			}
-			 			
-			 			res[i] = actNums[i] * pattern[patternIndex];
-			 			//System.out.print(nums[i] +"*" +pattern[patternIndex]+" ");
-			 			
-			 			elementTimes++;
-					}
-					//System.arraycopy(sumArray, o, res, 0, res.length);
-					numsForIndices.put(p, res);
-					timesEachPoint.increment(p);
-				}
-			}*/
-	 		//System.out.println();
-			/*int sum = 0;
-			for(Entry<Point, int[]> arr : numsForIndices.entrySet()) {
-				sum+=Arrays.stream(arr.getValue()).sum() * timesEachPoint.get(arr.getKey());
-			}
-	 		newNums[j] = lastDigit(sum);
-	 		timesEachElement++;*/
 		}
-		//System.out.println(arrayToInt(newNums));
-		//System.out.println(Arrays.toString(newNums));
-		//if(phase == 99) {
-			for(int i = 5977341; i<5977341+8; i++) {
-				System.out.println(res[i]);
-			}
-		//}
-		//actNums = newNums;
-		//}
-		return 0;
+		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;
+		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
index 325f1cbb..7841d8a9 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -4,7 +4,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -21,7 +20,6 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		char[][] grid = new char[48][48];
-		readDay(17);
 		IntcodeComputer ic = new IntcodeComputer(17, 1);
 		long res;
 		int x = 0, y =0;
@@ -43,7 +41,6 @@ public Object part1() throws IOException {
 				}
 			}
 		}
-		//System.out.println(y);
 		return result;
 	}
 	
@@ -67,7 +64,6 @@ public Object part2() throws IOException {
 				x++;
 			}
 		}
-		//StringBuilder input = new StringBuilder();
 		Point pos = findPos(grid, '^').get(0);
 		List<Instruction> instructions = new ArrayList<>();
 		List<Point> traversed = new ArrayList<>();
@@ -91,13 +87,11 @@ public Object part2() throws IOException {
 			}
 		}
 		good.add(toString(instructions.subList(start, instructions.size())));
-		good.stream().forEach(System.out::println);
 		String stuff = "A,A,B,C,B,A,C,B,C,A\nL,6,R,12,L,6,L,8,L,8\nL,6,R,12,R,8,L,8\nL,4,L,4,L,6\nn\n";
 		System.out.println(stuff);
 		long[] asciis = stuff.chars().mapToLong(e -> e).toArray();
 		ic = new IntcodeComputer(17, 2);
 		ic.setInput(asciis);
-		System.out.println(Arrays.toString(asciis));
 		while(true) {
 			if((res = ic.run())>255L)
 				return res;

From 424e5b0fcb601970deda62c8864854c085ed6a17 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 17:46:10 +0100
Subject: [PATCH 091/120] Path finding for day 15

---
 .../sbaars/adventofcode2019/days/Day15.java   | 20 ++---
 .../sbaars/adventofcode2019/days/Day17.java   |  2 +-
 .../adventofcode2019/pathfinding/Example.java | 75 +++++++++++++++++--
 .../adventofcode2019/pathfinding/Grid2d.java  |  4 +-
 4 files changed, 81 insertions(+), 20 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
index 668b92a0..58c70abb 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -13,12 +13,12 @@
 
 public class Day15 implements Day {
 	
-	private static final int UNEXPLORED = 3;
-	private static final int WALL = 0;
+	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 = 60;
-	private static final Point START_POINT = new Point(BOARD_SIZE/2,BOARD_SIZE/2);
+	private static final int BOARD_SIZE = 41;
+	private static final Point START_POINT = new Point(BOARD_SIZE/2+1,BOARD_SIZE/2+1);
 
 	public static void main(String[] args) throws IOException {
 		new Day15().printParts();
@@ -30,16 +30,14 @@ public Object part1() throws IOException {
 		Point pos = START_POINT;
 		int[][] grid = new int[BOARD_SIZE][BOARD_SIZE];
 		for(int[] row : grid) Arrays.fill(row, UNEXPLORED);
-		grid[pos.y][pos.x] = 0;
+		grid[pos.y][pos.x] = 1;
 		while(true) {
-			System.out.println("Current pos = "+pos);
-			Arrays.stream(grid).map(e -> Arrays.toString(e)).forEach(System.out::println);
 			explore(grid, pos, ic);
 			pos = moveToUnexploredPlace(grid, pos, ic);
 			if(pos == null) {
 				Grid2d map2d = new Grid2d(grid, false);
-				System.out.println(Arrays.deepToString(grid));
-				return map2d.findPath(START_POINT, findPos(grid, FINISH).get(0)).size();
+				Arrays.stream(grid).map(e -> Arrays.toString(e)).forEach(System.out::println);
+				return map2d.findPath(START_POINT, findPos(grid, FINISH).get(0)).size()-1;
 			}
 		}
 	}
@@ -59,7 +57,9 @@ private Point moveToUnexploredPlace(int[][] grid, Point pos, IntcodeComputer ic)
 	
 	private void traverseRoute(IntcodeComputer ic, Point pos, List<Point> route) {
 		for(Point p : route) {
-			ic.run(Direction.getByMove(pos, p).num);
+			if(ic.run(Direction.getByMove(pos, p).num)!=1L)
+				throw new IllegalStateException("Illegal state at "+pos+" execute to "+p);
+			pos = p;
 		}
 	}
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
index 7841d8a9..e7a2fceb 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -23,7 +23,6 @@ public Object part1() throws IOException {
 		IntcodeComputer ic = new IntcodeComputer(17, 1);
 		long res;
 		int x = 0, y =0;
-		int result = 0;
 		while((res = ic.run()) != IntcodeComputer.STOP_CODE) {
 			System.out.print((char)res);
 			if(res == 10) {
@@ -34,6 +33,7 @@ public Object part1() throws IOException {
 				x++;
 			}
 		}
+		int result = 0;
 		for(y = 1; y<grid.length-1; y++) {
 			for(x = 1; x<grid.length-1; x++) {
 				if(hasAdjecent(grid, new Point(x,y), '#')) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
index a8d039b3..cccb1cfc 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
@@ -1,18 +1,77 @@
 package com.sbaars.adventofcode2019.pathfinding;
 
 import java.awt.Point;
+import java.util.Arrays;
+import java.util.List;
+
+import com.sbaars.adventofcode2019.common.Direction;
 
 public class Example {
-	public Example() {
-		int[][] map = { { 0, 1, 0, 0, 0 }, 
-							{ 0, 0, 0, 1, 0 }, 
-							{ 1, 1, 1, 1, 0} };
-		Grid2d map2d = new Grid2d(map, false);
-		//System.out.println(map2d.findPath(new Point(0, 0), new Point(4, 2)));
-	}
+	
+	static int[][] grid = {{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 1, 1, 1, 0, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 1, 0, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 0, 0, 1, 0, 1, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 1, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}};
 
 	public static void main(String[] args) {
-		new Example();
+		Grid2d map2d = new Grid2d(grid, false);
+		Point start = new Point(7,27);
+		Point end = new Point(14,27);
+		grid[start.y][start.x] = 8;
+		List<Point> route = map2d.findPath(start, end);
+		System.out.println("Go from "+start+" to "+end+" by route "+route.subList(1, route.size()));
+		route.subList(1, route.size()).stream().forEach(p -> grid[p.y][p.x] = 9);//.peek(System.out::println);
+		for(Point p : route.subList(1, route.size())) {
+			System.out.println("Dir "+Direction.getByMove(start, p));
+			start = p;
+		}
+		Arrays.stream(grid).map(e -> Arrays.toString(e)).forEach(System.out::println);
 	}
 
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
index f93bb40c..461e50f1 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Grid2d.java
@@ -6,6 +6,8 @@
 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
@@ -65,7 +67,7 @@ public Set<MapNode> getNeighbours() {
 						continue;
 					}
 
-					if (map[j][i] < 1) {
+					if (map[j][i] == Day15.WALL || map[j][i] == Day15.UNEXPLORED) {
 						continue;
 					}
 

From 81b14527eddcb5265c8e17c9b54843eb62dad1cf Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 17:52:56 +0100
Subject: [PATCH 092/120] Moved day 15 part 2 to path finding

---
 .../sbaars/adventofcode2019/days/Day15.java   | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
index 58c70abb..4e3c10ed 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day15.java
@@ -19,6 +19,7 @@ public class Day15 implements Day {
 	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();
@@ -28,24 +29,22 @@ public static void main(String[] args) throws IOException {
 	public Object part1() throws IOException {
 		IntcodeComputer ic = new IntcodeComputer(15);
 		Point pos = START_POINT;
-		int[][] grid = new int[BOARD_SIZE][BOARD_SIZE];
 		for(int[] row : grid) Arrays.fill(row, UNEXPLORED);
 		grid[pos.y][pos.x] = 1;
 		while(true) {
-			explore(grid, pos, ic);
-			pos = moveToUnexploredPlace(grid, pos, ic);
+			explore(pos, ic);
+			pos = moveToUnexploredPlace(pos, ic);
 			if(pos == null) {
 				Grid2d map2d = new Grid2d(grid, false);
-				Arrays.stream(grid).map(e -> Arrays.toString(e)).forEach(System.out::println);
-				return map2d.findPath(START_POINT, findPos(grid, FINISH).get(0)).size()-1;
+				return map2d.findPath(START_POINT, findPos(FINISH).get(0)).size()-1;
 			}
 		}
 	}
 	
-	private Point moveToUnexploredPlace(int[][] grid, Point pos, IntcodeComputer ic) {
-		List<Point> corridorSpaces = findPos(grid, PATH);
+	private Point moveToUnexploredPlace(Point pos, IntcodeComputer ic) {
+		List<Point> corridorSpaces = findPos(PATH);
 		for(Point p : corridorSpaces) {
-			if(hasAdjecent(grid, p, UNEXPLORED)) {
+			if(hasAdjecent(p, UNEXPLORED)) {
 				Grid2d map2d = new Grid2d(grid, false);
 				List<Point> route = map2d.findPath(pos, p);
 				traverseRoute(ic, pos, route.subList(1, route.size()));
@@ -63,11 +62,11 @@ private void traverseRoute(IntcodeComputer ic, Point pos, List<Point> route) {
 		}
 	}
 
-	private boolean hasAdjecent(int[][] grid, Point pos, int tile) {
+	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<Point> findPos(int[][] grid, int tile) {
+	private List<Point> findPos(int tile) {
 		List<Point> positions = new ArrayList<>();
 		for(int y = 0; y<grid.length; y++) {
 			for(int x = 0; x<grid[y].length; x++) {
@@ -78,7 +77,7 @@ private List<Point> findPos(int[][] grid, int tile) {
 		return positions;
 	}
 
-	private void explore(int[][] grid, Point pos, IntcodeComputer ic) {
+	private void explore(Point pos, IntcodeComputer ic) {
 		Direction dir  = Direction.NORTH;
 		for(int i = 0; i<4;i++) {
 			Point move = dir.move(pos);
@@ -94,6 +93,7 @@ private void explore(int[][] grid, Point pos, IntcodeComputer ic) {
 	
 	@Override
 	public Object part2() throws IOException {
-		return 0;
+		Point oxygenLeak = findPos(FINISH).get(0);
+		return findPos(PATH).stream().mapToInt(e -> new Grid2d(grid, false).findPath(oxygenLeak, e).size()-1).max().getAsInt();
 	}
 }

From 32f6918c9c1c40a3330148e7dafc01813da3152a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 20:02:35 +0100
Subject: [PATCH 093/120] Find patterns automagically

---
 .../sbaars/adventofcode2019/days/Day17.java   | 126 +++++++++++-------
 1 file changed, 81 insertions(+), 45 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
index e7a2fceb..45d331e6 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -6,6 +6,7 @@
 import java.util.Arrays;
 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;
@@ -13,18 +14,13 @@
 
 public class Day17 implements Day {
 
-	public static void main(String[] args) throws IOException {
-		new Day17().printParts();
-	}
+	char[][] grid = new char[48][48];
 
-	@Override
-	public Object part1() throws IOException {
-		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) {
-			System.out.print((char)res);
 			if(res == 10) {
 				y++;
 				x= 0;
@@ -33,9 +29,17 @@ public Object part1() throws IOException {
 				x++;
 			}
 		}
+	}
+
+	public static void main(String[] args) throws IOException {
+		new Day17().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
 		int result = 0;
-		for(y = 1; y<grid.length-1; y++) {
-			for(x = 1; x<grid.length-1; x++) {
+		for(int y = 1; y<grid.length-1; y++) {
+			for(int x = 1; x<grid.length-1; x++) {
 				if(hasAdjecent(grid, new Point(x,y), '#')) {
 					result+=x*y;
 				}
@@ -43,27 +47,13 @@ public Object part1() throws IOException {
 		}
 		return result;
 	}
-	
+
 	private boolean hasAdjecent(char[][] grid, Point pos, char 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 && grid[pos.y][pos.x] == tile;
 	}
-	
+
 	@Override
 	public Object part2() throws IOException {
-		char[][] grid = new char[48][48];
-		readDay(17);
-		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++;
-			}
-		}
 		Point pos = findPos(grid, '^').get(0);
 		List<Instruction> instructions = new ArrayList<>();
 		List<Point> traversed = new ArrayList<>();
@@ -76,37 +66,58 @@ public Object part2() throws IOException {
 			instructions.add(new Instruction(n-1, dir.leftOf(robotDir) ? Dir.R : Dir.L));
 			robotDir = dir;
 		}
-		System.out.println(Arrays.toString(instructions.toArray()));
-		List<String> good = new ArrayList<>();
-		int start = 0;
-		for(int i = 1; i<instructions.size(); i++) {
-			List<Instruction> is = instructions.subList(start, i);
-			if(toString(is).length()>20) {
-				good.add(toString(instructions.subList(start, i-1)));
-				start = i-1;
-			}
-		}
-		good.add(toString(instructions.subList(start, instructions.size())));
-		String stuff = "A,A,B,C,B,A,C,B,C,A\nL,6,R,12,L,6,L,8,L,8\nL,6,R,12,R,8,L,8\nL,4,L,4,L,6\nn\n";
-		System.out.println(stuff);
-		long[] asciis = stuff.chars().mapToLong(e -> e).toArray();
-		ic = new IntcodeComputer(17, 2);
+		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) {
-			if((res = ic.run())>255L)
+			long res = ic.run();
+			if(res>255L)
 				return res;
 		}
 	}
 
+	private String findPatterns(List<Instruction> instructions) {
+		List<List<Instruction>> patterns = new ArrayList<>();
+		String patternString = "";
+		int start = 0;
+		for(int i = 0; i<instructions.size()-1; i++) {
+			List<Instruction> 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<Instruction> existing(List<Instruction> instructions, List<List<Instruction>> patterns, int i){
+		for(List<Instruction> pattern : patterns)
+			if(i+pattern.size() <= instructions.size() && instructions.subList(i, i+pattern.size()).equals(pattern))
+				return pattern;
+		return null;
+	}
+
+	private int occurrences(List<Instruction> instructions, List<Instruction> 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<Instruction> 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<Point> traversed) {
 		Direction dir = Direction.NORTH;
 		for(int i = 0; i<4; i++) {
@@ -129,12 +140,12 @@ private List<Point> findPos(char[][] grid, char tile) {
 		}
 		return positions;
 	}
-	
+
 	enum Dir{L,R}
 	class Instruction{
 		int amount;
 		Dir dir;
-		
+
 		public Instruction(int amount, Dir dir) {
 			super();
 			this.amount = amount;
@@ -145,5 +156,30 @@ public Instruction(int amount, Dir dir) {
 		public String toString() {
 			return dir.name()+","+amount;
 		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + amount;
+			result = prime * result + ((dir == null) ? 0 : dir.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Instruction other = (Instruction) obj;
+			if (amount != other.amount)
+				return false;
+			if (dir != other.dir)
+				return false;
+			return true;
+		}
 	}
 }

From cc9e6d2e58d64eaddf36f8fb88e4ced92f432ced Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 20:09:37 +0100
Subject: [PATCH 094/120] Got rid of the OCR

---
 .../sbaars/adventofcode2019/common/OCR.java   | 76 -------------------
 .../common/ProcessesImages.java               |  4 +-
 .../sbaars/adventofcode2019/days/Day11.java   |  5 +-
 .../sbaars/adventofcode2019/days/Day17.java   |  1 -
 .../sbaars/adventofcode2019/days/Day8.java    |  3 +-
 5 files changed, 5 insertions(+), 84 deletions(-)
 delete mode 100644 src/main/java/com/sbaars/adventofcode2019/common/OCR.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/OCR.java b/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
deleted file mode 100644
index a75fdf1e..00000000
--- a/src/main/java/com/sbaars/adventofcode2019/common/OCR.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.sbaars.adventofcode2019.common;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@SuppressWarnings("preview")
-public class OCR {
-	
-	List<String[]> characters = new ArrayList<>();
-
-	public OCR(String[] image) {
-		for(int i = 0; i<image[0].length(); i+=5) {
-			String[] character = new String[image.length];
-			for(int j = 0; j<character.length; j++) {
-				character[j] = image[j].substring(i,i+4);
-			}
-			characters.add(character);
-		}
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder result = new StringBuilder();
-		for(String[] character : characters) {
-			result.append(switch(character[0]) {
-				case "████" -> fullTop(character);
-				case "███ " -> threeTopLeft(character);
-				case "â–ˆ  â–ˆ" -> bothSides(character);
-				case " ██ " -> middleTwo(character);
-				case "  ██" -> 'J';
-				case "â–ˆ   " -> 'L';
-				default -> dontKnow(character);
-			});
-		}
-		return result.toString();
-	}
-
-	private char bothSides(String[] character) {
-		return switch(character[5]) {
-			case " ██ " -> 'U';
-			case "â–ˆ  â–ˆ" -> 'H';
-			default -> dontKnow(character);
-		};
-	}
-
-	private char middleTwo(String[] character) {
-		return switch(character[5]) {
-			case " ███" -> 'G';
-			case "â–ˆ  â–ˆ" -> 'A';
-			default -> dontKnow(character);
-		};
-	}
-
-	private char dontKnow(String[] character) {
-		Arrays.stream(character).forEach(System.out::println);
-		throw new IllegalArgumentException("I don't know your character yet!");
-	}
-	
-	private char fullTop(String[] character) {
-		return switch(character[5]) {
-			case "â–ˆ   " -> 'F';
-			case "████" -> 'E';
-			default -> dontKnow(character);
-		};
-	}
-
-	private char threeTopLeft(String[] character) {
-		return switch(character[5]) {
-			case "â–ˆ   " -> 'P';
-			case "â–ˆ  â–ˆ" -> 'R';
-			default -> dontKnow(character);
-		};
-	}
-	
-}
diff --git a/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java b/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java
index edb7eadd..e4de03c2 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/ProcessesImages.java
@@ -4,7 +4,7 @@
 import java.util.stream.Collectors;
 
 public interface ProcessesImages {
-	public default String[] createAsciiArray(int[][] pixels) {
-		return Arrays.stream(pixels).map(a -> Arrays.stream(a).boxed().map(x -> x == 0 ? " " : "â–ˆ").collect(Collectors.joining())).toArray(String[]::new);
+	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/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index 0ef8815a..e7a660b0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -6,7 +6,6 @@
 import java.util.Set;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.common.OCR;
 import com.sbaars.adventofcode2019.common.ProcessesImages;
 import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
 
@@ -50,7 +49,7 @@ private Object robotWalk(boolean startWhite) throws IOException {
 		return startWhite ? constructImage(whitePlaces) : paintedOnce.size();
 	}
 	
-	private OCR constructImage(Set<Point> whitePlaces) {
+	private String constructImage(Set<Point> 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));
@@ -59,7 +58,7 @@ private OCR constructImage(Set<Point> whitePlaces) {
 		int[][] places = new int[sizey][sizex];
 		for(Point p : whitePlaces)
 			places[p.y][p.x] = 1;
-		return new OCR(createAsciiArray(places));
+		return printAsciiArray(places);
 	}
 
 	@Override
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
index 45d331e6..d205dcb0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -3,7 +3,6 @@
 import java.awt.Point;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index d2995743..4887d8d8 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -6,7 +6,6 @@
 import java.util.stream.IntStream;
 
 import com.sbaars.adventofcode2019.common.Day;
-import com.sbaars.adventofcode2019.common.OCR;
 import com.sbaars.adventofcode2019.common.ProcessesImages;
 import com.sbaars.adventofcode2019.util.CountMap;
 
@@ -49,7 +48,7 @@ private List<CountMap<Integer>> countPixels(int[] pixels) {
 	public Object part2() throws IOException {
 		int[][] pixelArrays = splitArray(readPixels(), 100, SIZE);
 		int[] finalPixels = determineFinalImage(pixelArrays);
-		return new OCR(createAsciiArray(splitArray(finalPixels, DIM_X, DIM_Y)));
+		return printAsciiArray(splitArray(finalPixels, DIM_X, DIM_Y));
 	}
 
 	private int[] determineFinalImage(int[][] pixelArrays) {

From 1cde281ba98e95981ad2090a4bf03f2b10aaa7e4 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 20:13:09 +0100
Subject: [PATCH 095/120] Fixed day 3

---
 .../sbaars/adventofcode2019/common/Direction.java    | 12 +++++-------
 .../java/com/sbaars/adventofcode2019/days/Day3.java  |  3 +--
 2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
index 8f85dbe1..fafe9ff1 100644
--- a/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
+++ b/src/main/java/com/sbaars/adventofcode2019/common/Direction.java
@@ -4,20 +4,18 @@
 import java.util.Arrays;
 
 public enum Direction {
-	NORTH(1), EAST(4), SOUTH(2), WEST(3);
+	NORTH(1, 'U'), EAST(4, 'R'), SOUTH(2, 'D'), WEST(3, 'L');
 	
 	public final int num;
+	public final int code;
 	
-	private Direction(int num) {
+	private Direction(int num, char code) {
 		this.num = num;
-	}
-	
-	public char directionCode() {
-		return name().charAt(0);
+		this.code = code;
 	}
 	
 	public static Direction getByDirCode(char code) {
-		return Arrays.stream(values()).filter(e -> e.directionCode() == code).findAny().get();
+		return Arrays.stream(values()).filter(e -> e.code == code).findAny().get();
 	}
 	
 	public Direction turn(boolean right) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 6a8c22e2..28ae2696 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -22,8 +22,7 @@ public Day3() throws IOException {
 		this.intersect = calculateDistance(walks2, walkedLocations, true);
 	}
 	
-	public static void main(String[] args) throws IOException
-    {
+	public static void main(String[] args) throws IOException {
     	new Day3().printParts();
     }
 

From 7aad744727c69b548c81a177a2f4d4af2b92d427 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Tue, 17 Dec 2019 20:16:21 +0100
Subject: [PATCH 096/120] Updated Main and Readme

---
 README.md                                     | 36 +++++++++++++++++--
 .../com/sbaars/adventofcode2019/Main.java     |  2 +-
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 23e30683..ae02bed5 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,10 @@ Days:
 - [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)
 
 Output of running [Main.java](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/Main.java):
 ```
@@ -48,7 +52,13 @@ Part 2: 89603079
 
 Day 8:
 Part 1: 1360
-Part 2: FPUAR
+Part 2: 
+████ ███  █  █  ██  ███  
+â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ 
+███  █  █ █  █ █  █ █  █ 
+█    ███  █  █ ████ ███  
+â–ˆ    â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ â–ˆ  
+█    █     ██  █  █ █  █ 
 
 Day 9:
 Part 1: 2518058886
@@ -60,7 +70,13 @@ Part 2: 1419
 
 Day 11:
 Part 1: 2172
-Part 2: JELEFGHP
+Part 2: 
+  ██ ████ █    ████ ████  ██  █  █ ███ 
+   â–ˆ â–ˆ    â–ˆ    â–ˆ    â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ  â–ˆ
+   █ ███  █    ███  ███  █    ████ █  █
+   █ █    █    █    █    █ ██ █  █ ███ 
+â–ˆ  â–ˆ â–ˆ    â–ˆ    â–ˆ    â–ˆ    â–ˆ  â–ˆ â–ˆ  â–ˆ â–ˆ   
+ ██  ████ ████ ████ █     ███ █  █ █   
 
 Day 12:
 Part 1: 13399
@@ -69,4 +85,20 @@ 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
 ```
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/Main.java b/src/main/java/com/sbaars/adventofcode2019/Main.java
index 59227840..5e7a3622 100644
--- a/src/main/java/com/sbaars/adventofcode2019/Main.java
+++ b/src/main/java/com/sbaars/adventofcode2019/Main.java
@@ -7,7 +7,7 @@
 
 public class Main {
 	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException, InvocationTargetException, NoSuchMethodException {
-		for(int day = 1; day<=13; day++) {
+		for(int day = 1; day<=17; day++) {
 			System.out.println("Day "+day+":");
 			Day instance = (Day)Class.forName("com.sbaars.adventofcode2019.days.Day"+day).getDeclaredConstructor().newInstance();
 			instance.printParts();

From b2282fcf46e0a594ab1b1a8a8cb0104333ce79d0 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 07:28:07 +0100
Subject: [PATCH 097/120] ...

---
 .../sbaars/adventofcode2019/days/Day18.java   | 115 ++++++++++++++
 .../pathfinding/CharGrid2d.java               | 143 ++++++++++++++++++
 .../pathfinding/PathFinding.java              |   3 +-
 src/main/resources/day18.txt                  |  81 ++++++++++
 src/main/resources/day19.txt                  |   5 +
 5 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day18.java
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
 create mode 100644 src/main/resources/day18.txt
 create mode 100644 src/main/resources/day19.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
new file mode 100644
index 00000000..0b76e877
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -0,0 +1,115 @@
+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 java.util.Random;
+import java.util.stream.Collectors;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.pathfinding.CharGrid2d;
+
+public class Day18 implements Day {
+	
+	char[][] grid;
+	CharGrid2d charGrid;
+	
+	public Day18() throws IOException {
+		grid = Arrays.stream(readDay(19).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
+		charGrid = new CharGrid2d(grid, false);
+	}	
+
+	public static void main(String[] args) throws IOException {
+		new Day18().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		Point me = findPos('@').get(0);
+		//List<Character> collectedKeys = new ArrayList<>();
+		//int keysToCollect = findPos('a', 'z').size();
+		List<Point> keys = findPos('a', 'z');
+		//List<Point> doors = findPos('A', 'Z');
+		/*int steps = 0;
+		//while(collectedKeys.size()<keysToCollect) {
+			//System.out.println("Keys = "+Arrays.toString(collectedKeys.toArray()));
+			//Arrays.stream(grid).map(e -> new String(e)).forEach(System.out::println);
+			final Point meNow = me;
+			List<List<Point>> possibleMoves = keys.stream().map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList());
+			//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
+			//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
+			List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
+			steps += takenMove.size()-1;
+			grid[me.y][me.x] = '.';
+			me = takenMove.get(takenMove.size()-1);
+			char collected = grid[me.y][me.x];
+			//System.out.println((takenMove.size()-1)+" steps to "+collected);
+			if(collected >= 'a' && collected <= 'z') {
+				collectedKeys.add(Character.toUpperCase(collected));
+				doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
+				doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
+				keys.remove(me);
+			} 
+			grid[me.y][me.x] = '@';
+		//}
+		if(steps<5992)
+		System.out.println(steps);
+		}*/
+		//System.out.println(Arrays.toString(reachableKeys.toArray()));
+		return findSteps(me, new ArrayList<>(), keys);
+	}
+	
+	public int findSteps(Point me, List<Character> collectedKeys, List<Point> keys) {
+		List<List<Point>> possibleMoves = keys.stream().map(e -> charGrid.findPath(me, e, collectedKeys)).filter(e -> !e.isEmpty()).collect(Collectors.toList());
+		
+		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
+		//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
+		List<Integer> nSteps = new ArrayList<>();
+		for(List<Point> takenMove : possibleMoves) {
+		//List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
+			//grid[me.y][me.x] = '.';
+			//me = takenMove.get(takenMove.size()-1);
+			Point newLoc = takenMove.get(takenMove.size()-1);
+			char collected = grid[me.y][me.x];
+			//System.out.println((takenMove.size()-1)+" steps to "+collected);
+			if(collected >= 'a' && collected <= 'z') {
+				collectedKeys.add(Character.toUpperCase(collected));
+				//doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
+				//doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
+				keys.remove(newLoc);
+			} 
+			//grid[newLoc.y][newLoc.x] = '@';
+			nSteps.add(findSteps(newLoc, new ArrayList<>(collectedKeys), new ArrayList<>(keys))+takenMove.size()-1);
+		}
+		return nSteps.stream().mapToInt(e -> e).min().orElse(0);
+	}
+	
+	private List<Point> findPos(char tile) {
+		List<Point> positions = new ArrayList<>();
+		for(int y = 0; y<grid.length; y++) {
+			for(int x = 0; x<grid[y].length; x++) {
+				if(grid[y][x] == tile)
+					positions.add(new Point(x, y));
+			}
+		}
+		return positions;
+	}
+	
+	private List<Point> findPos(char tile, char tile2) {
+		List<Point> positions = new ArrayList<>();
+		for(int y = 0; y<grid.length; y++) {
+			for(int x = 0; x<grid[y].length; x++) {
+				if(grid[y][x] >= tile && grid[y][x] <= tile2)
+					positions.add(new Point(x, y));
+			}
+		}
+		return positions;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		return 0;
+	}
+}
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..97fb53bf
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
@@ -0,0 +1,143 @@
+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<Character> collectedKeys;
+
+	/**
+	 * A node in a 2d map. This is simply the coordinates of the point.
+	 * 
+	 * @author Ben Ruijl
+	 * 
+	 */
+	public class MapNode implements Node<MapNode> {
+		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<MapNode> getNeighbours() {
+			Set<MapNode> neighbours = new HashSet<MapNode>();
+
+			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] == '#' || (map[j][i]>='A' && map[j][i]<='Z' && !collectedKeys.contains(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<Point> findPath(Point start, Point end, List<Character> collectedKeys) {
+		this.collectedKeys = collectedKeys;
+		char removed = '.';
+		if(map[end.y][end.x] >='A' && map[end.y][end.x]<='Z') {
+			removed = map[end.y][end.x];
+			map[end.y][end.x] = '.';
+		}
+		List<Point> res = PathFinding.doAStar(new MapNode(start.x, start.y), new MapNode(end.x, end.y)).stream().map(MapNode::toPoint).collect(Collectors.toList());
+		if(removed >='A' && removed<='Z') {
+			map[end.y][end.x] = removed;
+		}
+		return res;
+	}
+
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
index 95369ddc..7c13a084 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/PathFinding.java
@@ -1,4 +1,5 @@
 package com.sbaars.adventofcode2019.pathfinding;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -80,7 +81,7 @@ public int compare(T nodeA, T nodeB) {
 			}
 		}
 
-		return route;
+		return new ArrayList<>();
 	}
 
 }
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..7345fa09
--- /dev/null
+++ b/src/main/resources/day19.txt
@@ -0,0 +1,5 @@
+########################
+#f.D.E.e.C.b.A.@.a.B.c.#
+######################.#
+#d.....................#
+########################
\ No newline at end of file

From 8453b5f6b108d2d4a22dea9ea6c0fa8c7cb7b472 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 07:49:06 +0100
Subject: [PATCH 098/120] Day 18 Part 1 : Recursive

---
 .../java/com/sbaars/adventofcode2019/days/Day18.java | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index 0b76e877..b38cd7a3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -17,7 +17,7 @@ public class Day18 implements Day {
 	CharGrid2d charGrid;
 	
 	public Day18() throws IOException {
-		grid = Arrays.stream(readDay(19).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
+		grid = Arrays.stream(readDay(18).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
 		charGrid = new CharGrid2d(grid, false);
 	}	
 
@@ -63,23 +63,23 @@ public Object part1() throws IOException {
 	
 	public int findSteps(Point me, List<Character> collectedKeys, List<Point> keys) {
 		List<List<Point>> possibleMoves = keys.stream().map(e -> charGrid.findPath(me, e, collectedKeys)).filter(e -> !e.isEmpty()).collect(Collectors.toList());
-		
+		//System.out.println("moves "+possibleMoves.size());
 		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
 		//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
+		System.out.println(possibleMoves.size()+", "+collectedKeys.size());
 		List<Integer> nSteps = new ArrayList<>();
 		for(List<Point> takenMove : possibleMoves) {
 		//List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
 			//grid[me.y][me.x] = '.';
 			//me = takenMove.get(takenMove.size()-1);
 			Point newLoc = takenMove.get(takenMove.size()-1);
-			char collected = grid[me.y][me.x];
+			char collected = grid[newLoc.y][newLoc.x];
 			//System.out.println((takenMove.size()-1)+" steps to "+collected);
-			if(collected >= 'a' && collected <= 'z') {
-				collectedKeys.add(Character.toUpperCase(collected));
+			collectedKeys.add(Character.toUpperCase(collected));
 				//doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
 				//doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
 				keys.remove(newLoc);
-			} 
+			//System.out.println(collected);
 			//grid[newLoc.y][newLoc.x] = '@';
 			nSteps.add(findSteps(newLoc, new ArrayList<>(collectedKeys), new ArrayList<>(keys))+takenMove.size()-1);
 		}

From c416ed4a4d81ee63579b97fb2a741b36b799d2a3 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 08:37:48 +0100
Subject: [PATCH 099/120] Further optimized  part 1

---
 .../sbaars/adventofcode2019/days/Day18.java   | 101 ++++++++++++++++--
 .../pathfinding/CharGrid2d.java               |  16 +--
 2 files changed, 95 insertions(+), 22 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index b38cd7a3..6c3758b2 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -4,8 +4,10 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
-import java.util.Random;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.stream.Collectors;
 
 import com.sbaars.adventofcode2019.common.Day;
@@ -24,6 +26,51 @@ public Day18() throws IOException {
 	public static void main(String[] args) throws IOException {
 		new Day18().printParts();
 	}
+	
+	class Route {
+		Point start;
+		Point end;
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((end == null) ? 0 : end.hashCode());
+			result = prime * result + ((start == null) ? 0 : start.hashCode());
+			return result;
+		}
+		public Route(Point start, Point end) {
+			super();
+			this.start = start;
+			this.end = end;
+		}
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Route other = (Route) obj;
+			if (end == null) {
+				if (other.end != null)
+					return false;
+			} else if (!end.equals(other.end))
+				return false;
+			if (start == null) {
+				if (other.start != null)
+					return false;
+			} else if (!start.equals(other.start))
+				return false;
+			return true;
+		}
+		@Override
+		public String toString() {
+			return "Route [start=" + start + ", end=" + end + "]";
+		}
+		
+		
+	}
 
 	@Override
 	public Object part1() throws IOException {
@@ -31,6 +78,16 @@ public Object part1() throws IOException {
 		//List<Character> collectedKeys = new ArrayList<>();
 		//int keysToCollect = findPos('a', 'z').size();
 		List<Point> keys = findPos('a', 'z');
+		Map<Route, List<Point>> routes = new HashMap<>();
+		List<Point> requiredRoutes = new ArrayList<>(keys);
+		requiredRoutes.add(me);
+		for(int i = 0; i<requiredRoutes.size(); i++) {
+			for(int j = i+1; j<requiredRoutes.size(); j++) {
+				List<Point> r = charGrid.findPath(requiredRoutes.get(i), requiredRoutes.get(j));
+				//System.out.println(r.size()+", "+new Route(requiredRoutes.get(i), requiredRoutes.get(j)));
+				routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
+			}
+		}
 		//List<Point> doors = findPos('A', 'Z');
 		/*int steps = 0;
 		//while(collectedKeys.size()<keysToCollect) {
@@ -58,30 +115,56 @@ public Object part1() throws IOException {
 		System.out.println(steps);
 		}*/
 		//System.out.println(Arrays.toString(reachableKeys.toArray()));
-		return findSteps(me, new ArrayList<>(), keys);
+		return findSteps(0, me, new ArrayList<>(), keys, routes);
 	}
 	
-	public int findSteps(Point me, List<Character> collectedKeys, List<Point> keys) {
-		List<List<Point>> possibleMoves = keys.stream().map(e -> charGrid.findPath(me, e, collectedKeys)).filter(e -> !e.isEmpty()).collect(Collectors.toList());
+	public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
+		List<Point> p = routes.get(new Route(p1, p2));
+		if(p != null)
+			return p;
+		else return routes.get(new Route(p2, p1));
+	}
+	
+	public boolean canTakeRoute(List<Point> route, List<Character> 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;
+	}
+	
+	int lowest = Integer.MAX_VALUE;
+	public int findSteps(int currentSteps, Point me, List<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
+		if(keys.isEmpty() && currentSteps<lowest) {
+			lowest = currentSteps;
+			System.out.println(lowest);
+		} else if(currentSteps>=lowest) {
+			return currentSteps;
+		}
+		
+		List<List<Point>> possibleMoves = keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
 		//System.out.println("moves "+possibleMoves.size());
 		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
 		//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
-		System.out.println(possibleMoves.size()+", "+collectedKeys.size());
+		//System.out.println(possibleMoves.size()+", "+collectedKeys.size());
 		List<Integer> nSteps = new ArrayList<>();
 		for(List<Point> takenMove : possibleMoves) {
 		//List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
 			//grid[me.y][me.x] = '.';
 			//me = takenMove.get(takenMove.size()-1);
-			Point newLoc = takenMove.get(takenMove.size()-1);
+			List<Character> myKeys = new ArrayList<>(collectedKeys);
+			List<Point> keyLocs = new ArrayList<>(keys);
+			Point newLoc = me.equals(takenMove.get(0)) ? takenMove.get(takenMove.size()-1) : takenMove.get(0);
 			char collected = grid[newLoc.y][newLoc.x];
 			//System.out.println((takenMove.size()-1)+" steps to "+collected);
-			collectedKeys.add(Character.toUpperCase(collected));
+			myKeys.add(Character.toUpperCase(collected));
 				//doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
 				//doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
-				keys.remove(newLoc);
+			keyLocs.remove(newLoc);
 			//System.out.println(collected);
 			//grid[newLoc.y][newLoc.x] = '@';
-			nSteps.add(findSteps(newLoc, new ArrayList<>(collectedKeys), new ArrayList<>(keys))+takenMove.size()-1);
+			nSteps.add(findSteps(currentSteps + takenMove.size()-1, newLoc, myKeys, keyLocs, routes));
 		}
 		return nSteps.stream().mapToInt(e -> e).min().orElse(0);
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
index 97fb53bf..929326ef 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
@@ -66,7 +66,7 @@ public Set<MapNode> getNeighbours() {
 						continue;
 					}
 
-					if (map[j][i] == '#' || (map[j][i]>='A' && map[j][i]<='Z' && !collectedKeys.contains(map[j][i]))) {
+					if (map[j][i] == '#'/* || (map[j][i]>='A' && map[j][i]<='Z' && !collectedKeys.contains(map[j][i]))*/) {
 						continue;
 					}
 
@@ -126,18 +126,8 @@ public CharGrid2d(char[][] map, boolean allowDiagonal) {
 		this.allowDiagonal = allowDiagonal;
 	}
 
-	public List<Point> findPath(Point start, Point end, List<Character> collectedKeys) {
-		this.collectedKeys = collectedKeys;
-		char removed = '.';
-		if(map[end.y][end.x] >='A' && map[end.y][end.x]<='Z') {
-			removed = map[end.y][end.x];
-			map[end.y][end.x] = '.';
-		}
-		List<Point> res = PathFinding.doAStar(new MapNode(start.x, start.y), new MapNode(end.x, end.y)).stream().map(MapNode::toPoint).collect(Collectors.toList());
-		if(removed >='A' && removed<='Z') {
-			map[end.y][end.x] = removed;
-		}
-		return res;
+	public List<Point> 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());
 	}
 
 }

From 8f4999b1ab1a06a2a9f015346af26d3f7d4902d0 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 18:59:54 +0100
Subject: [PATCH 100/120] Day 18: Optimized caching

---
 .../sbaars/adventofcode2019/days/Day11.java   |  3 +-
 .../sbaars/adventofcode2019/days/Day18.java   | 70 ++++++++++++++++---
 .../sbaars/adventofcode2019/days/Day3.java    |  3 +-
 3 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
index e7a660b0..934b1201 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day11.java
@@ -6,11 +6,10 @@
 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;
 
-import com.sbaars.adventofcode2019.common.Direction;
-
 public class Day11 implements Day, ProcessesImages {
 
 	public static void main(String[] args) throws IOException {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index 6c3758b2..057cd389 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -7,7 +7,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
+import java.util.TreeSet;
 import java.util.stream.Collectors;
 
 import com.sbaars.adventofcode2019.common.Day;
@@ -70,6 +70,47 @@ public String toString() {
 		}
 		
 		
+	}
+	
+	class State{
+		Point me;
+		TreeSet<Character> keys;
+		public State(Point me, TreeSet<Character> keys) {
+			super();
+			this.me = me;
+			this.keys = keys;
+		}
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((keys == null) ? 0 : keys.hashCode());
+			result = prime * result + ((me == null) ? 0 : me.hashCode());
+			return result;
+		}
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			State other = (State) obj;
+			if (keys == null) {
+				if (other.keys != null)
+					return false;
+			} else if (!keys.equals(other.keys))
+				return false;
+			if (me == null) {
+				if (other.me != null)
+					return false;
+			} else if (!me.equals(other.me))
+				return false;
+			return true;
+		}
+		
+		
 	}
 
 	@Override
@@ -115,7 +156,7 @@ public Object part1() throws IOException {
 		System.out.println(steps);
 		}*/
 		//System.out.println(Arrays.toString(reachableKeys.toArray()));
-		return findSteps(0, me, new ArrayList<>(), keys, routes);
+		return findSteps(me, new TreeSet<>(), keys, routes);
 	}
 	
 	public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
@@ -125,7 +166,7 @@ public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
 		else return routes.get(new Route(p2, p1));
 	}
 	
-	public boolean canTakeRoute(List<Point> route, List<Character> keys) {
+	public boolean canTakeRoute(List<Point> route, TreeSet<Character> 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;
@@ -134,15 +175,19 @@ public boolean canTakeRoute(List<Point> route, List<Character> keys) {
 		return true;
 	}
 	
-	int lowest = Integer.MAX_VALUE;
-	public int findSteps(int currentSteps, Point me, List<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
-		if(keys.isEmpty() && currentSteps<lowest) {
+	//int lowest = Integer.MAX_VALUE;
+	Map<State, Integer> cachedResult = new HashMap<>();
+	public int findSteps(Point me, TreeSet<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
+		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
+		if(cachedRes!=null)
+			return cachedRes;
+		/*if(keys.isEmpty() && currentSteps<lowest) {
 			lowest = currentSteps;
 			System.out.println(lowest);
 		} else if(currentSteps>=lowest) {
 			return currentSteps;
-		}
-		
+		}*/
+		//System.out.println(Arrays.toString(collectedKeys.toArray()));
 		List<List<Point>> possibleMoves = keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
 		//System.out.println("moves "+possibleMoves.size());
 		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
@@ -153,7 +198,7 @@ public int findSteps(int currentSteps, Point me, List<Character> collectedKeys,
 		//List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
 			//grid[me.y][me.x] = '.';
 			//me = takenMove.get(takenMove.size()-1);
-			List<Character> myKeys = new ArrayList<>(collectedKeys);
+			TreeSet<Character> myKeys = new TreeSet<>(collectedKeys);
 			List<Point> keyLocs = new ArrayList<>(keys);
 			Point newLoc = me.equals(takenMove.get(0)) ? takenMove.get(takenMove.size()-1) : takenMove.get(0);
 			char collected = grid[newLoc.y][newLoc.x];
@@ -164,9 +209,12 @@ public int findSteps(int currentSteps, Point me, List<Character> collectedKeys,
 			keyLocs.remove(newLoc);
 			//System.out.println(collected);
 			//grid[newLoc.y][newLoc.x] = '@';
-			nSteps.add(findSteps(currentSteps + takenMove.size()-1, newLoc, myKeys, keyLocs, routes));
+			//System.out.println("Taken move "+collected+" for "+(takenMove.size()-1));
+			nSteps.add(findSteps(newLoc, myKeys, keyLocs, routes) + takenMove.size()-1);
 		}
-		return nSteps.stream().mapToInt(e -> e).min().orElse(0);
+		int res = nSteps.stream().mapToInt(e -> e).min().orElse(0);
+		cachedResult.put(new State(me, collectedKeys), res);
+		return res;
 	}
 	
 	private List<Point> findPos(char tile) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 28ae2696..267d2895 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -6,9 +6,8 @@
 import java.util.HashSet;
 import java.util.Set;
 
-import com.sbaars.adventofcode2019.common.Direction;
-
 import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.common.Direction;
 
 public class Day3 implements Day
 {	

From cc1f58741add0ac3ec0b09332984e27be63027a0 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 19:28:19 +0100
Subject: [PATCH 101/120] Different approach

---
 .../sbaars/adventofcode2019/days/Day18.java   | 50 ++++++++++++-------
 .../sbaars/adventofcode2019/util/Pair.java    | 12 +++++
 2 files changed, 43 insertions(+), 19 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/util/Pair.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index 057cd389..ae8e9a6f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -15,12 +15,19 @@
 
 public class Day18 implements Day {
 	
-	char[][] grid;
-	CharGrid2d charGrid;
+	private final char[][] grid;
+	private final CharGrid2d charGrid;
+	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 {
@@ -73,9 +80,9 @@ public String toString() {
 	}
 	
 	class State{
-		Point me;
+		List<Point> me;
 		TreeSet<Character> keys;
-		public State(Point me, TreeSet<Character> keys) {
+		public State(List<Point> me, TreeSet<Character> keys) {
 			super();
 			this.me = me;
 			this.keys = keys;
@@ -110,16 +117,16 @@ public boolean equals(Object obj) {
 			return true;
 		}
 		
-		
 	}
 
 	@Override
 	public Object part1() throws IOException {
-		Point me = findPos('@').get(0);
+		List<Point> me = new ArrayList<>();
+		me.add(middle);
 		//List<Character> collectedKeys = new ArrayList<>();
 		//int keysToCollect = findPos('a', 'z').size();
 		List<Point> keys = findPos('a', 'z');
-		Map<Route, List<Point>> routes = new HashMap<>();
+		/*Map<Route, List<Point>> routes = new HashMap<>();
 		List<Point> requiredRoutes = new ArrayList<>(keys);
 		requiredRoutes.add(me);
 		for(int i = 0; i<requiredRoutes.size(); i++) {
@@ -128,7 +135,7 @@ public Object part1() throws IOException {
 				//System.out.println(r.size()+", "+new Route(requiredRoutes.get(i), requiredRoutes.get(j)));
 				routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
 			}
-		}
+		}*/
 		//List<Point> doors = findPos('A', 'Z');
 		/*int steps = 0;
 		//while(collectedKeys.size()<keysToCollect) {
@@ -156,14 +163,17 @@ public Object part1() throws IOException {
 		System.out.println(steps);
 		}*/
 		//System.out.println(Arrays.toString(reachableKeys.toArray()));
-		return findSteps(me, new TreeSet<>(), keys, routes);
+		return findSteps(me, new TreeSet<>(), keys);
 	}
 	
-	public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
-		List<Point> p = routes.get(new Route(p1, p2));
-		if(p != null)
-			return p;
-		else return routes.get(new Route(p2, p1));
+	public List<List<Point>> getRoute(List<Point> me, Point p){
+		List<List<Point>> points = new ArrayList<>();
+		me.forEach(m -> points.add(charGrid.findPath(m, p)));
+		return points;
+		//List<Point> p = routes.get(new Route(p1, p2));
+		//if(p != null)
+		//	return p;
+		//else return routes.get(new Route(p2, p1));
 	}
 	
 	public boolean canTakeRoute(List<Point> route, TreeSet<Character> keys) {
@@ -177,7 +187,7 @@ public boolean canTakeRoute(List<Point> route, TreeSet<Character> keys) {
 	
 	//int lowest = Integer.MAX_VALUE;
 	Map<State, Integer> cachedResult = new HashMap<>();
-	public int findSteps(Point me, TreeSet<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
+	public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Point> keys) {
 		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
 		if(cachedRes!=null)
 			return cachedRes;
@@ -187,8 +197,8 @@ public int findSteps(Point me, TreeSet<Character> collectedKeys, List<Point> key
 		} else if(currentSteps>=lowest) {
 			return currentSteps;
 		}*/
-		//System.out.println(Arrays.toString(collectedKeys.toArray()));
-		List<List<Point>> possibleMoves = keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
+		List<List<Point>> possibleMoves = me.stream().flatMap(m -> keys.stream().map(p -> charGrid.findPath(m, p))).filter(e -> !e.isEmpty()).collect(Collectors.toList());//keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
+		System.out.println(Arrays.toString(collectedKeys.toArray())+possibleMoves.size());
 		//System.out.println("moves "+possibleMoves.size());
 		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
 		//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
@@ -200,17 +210,19 @@ public int findSteps(Point me, TreeSet<Character> collectedKeys, List<Point> key
 			//me = takenMove.get(takenMove.size()-1);
 			TreeSet<Character> myKeys = new TreeSet<>(collectedKeys);
 			List<Point> keyLocs = new ArrayList<>(keys);
-			Point newLoc = me.equals(takenMove.get(0)) ? takenMove.get(takenMove.size()-1) : takenMove.get(0);
+			Point newLoc = takenMove.get(takenMove.size()-1);
 			char collected = grid[newLoc.y][newLoc.x];
 			//System.out.println((takenMove.size()-1)+" steps to "+collected);
 			myKeys.add(Character.toUpperCase(collected));
 				//doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
 				//doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
 			keyLocs.remove(newLoc);
+			List<Point> me2 = new ArrayList<>(me);
+			me2.set(me.indexOf(takenMove.get(0)), newLoc);
 			//System.out.println(collected);
 			//grid[newLoc.y][newLoc.x] = '@';
 			//System.out.println("Taken move "+collected+" for "+(takenMove.size()-1));
-			nSteps.add(findSteps(newLoc, myKeys, keyLocs, routes) + takenMove.size()-1);
+			nSteps.add(findSteps(me2, myKeys, keyLocs) + takenMove.size()-1);
 		}
 		int res = nSteps.stream().mapToInt(e -> e).min().orElse(0);
 		cachedResult.put(new State(me, collectedKeys), res);
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/Pair.java b/src/main/java/com/sbaars/adventofcode2019/util/Pair.java
new file mode 100644
index 00000000..d07dbc5f
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/util/Pair.java
@@ -0,0 +1,12 @@
+package com.sbaars.adventofcode2019.util;
+
+public class Pair<K, V> {
+	public final K fst;
+	public final V snd;
+	
+	public Pair(K key, V value) {
+		super();
+		this.fst = key;
+		this.snd = value;
+	}
+}

From 5fe3d18452bbb12a51a983ac933004887c7c86b8 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 19:45:40 +0100
Subject: [PATCH 102/120] More generic algorithm

---
 .../sbaars/adventofcode2019/days/Day18.java   | 51 +++++++++++--------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index ae8e9a6f..d4eb965b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -7,6 +7,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
@@ -123,19 +124,23 @@ public boolean equals(Object obj) {
 	public Object part1() throws IOException {
 		List<Point> me = new ArrayList<>();
 		me.add(middle);
+		return findRoutes(me);
+	}
+
+	private Object findRoutes(List<Point> me) {
 		//List<Character> collectedKeys = new ArrayList<>();
 		//int keysToCollect = findPos('a', 'z').size();
 		List<Point> keys = findPos('a', 'z');
-		/*Map<Route, List<Point>> routes = new HashMap<>();
+		Map<Route, List<Point>> routes = new HashMap<>();
 		List<Point> requiredRoutes = new ArrayList<>(keys);
-		requiredRoutes.add(me);
+		requiredRoutes.addAll(me);
 		for(int i = 0; i<requiredRoutes.size(); i++) {
 			for(int j = i+1; j<requiredRoutes.size(); j++) {
 				List<Point> r = charGrid.findPath(requiredRoutes.get(i), requiredRoutes.get(j));
-				//System.out.println(r.size()+", "+new Route(requiredRoutes.get(i), requiredRoutes.get(j)));
-				routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
+				if(!r.isEmpty())
+					routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
 			}
-		}*/
+		}
 		//List<Point> doors = findPos('A', 'Z');
 		/*int steps = 0;
 		//while(collectedKeys.size()<keysToCollect) {
@@ -163,17 +168,14 @@ public Object part1() throws IOException {
 		System.out.println(steps);
 		}*/
 		//System.out.println(Arrays.toString(reachableKeys.toArray()));
-		return findSteps(me, new TreeSet<>(), keys);
+		return findSteps(me, new TreeSet<>(), keys, routes);
 	}
 	
-	public List<List<Point>> getRoute(List<Point> me, Point p){
-		List<List<Point>> points = new ArrayList<>();
-		me.forEach(m -> points.add(charGrid.findPath(m, p)));
-		return points;
-		//List<Point> p = routes.get(new Route(p1, p2));
-		//if(p != null)
-		//	return p;
-		//else return routes.get(new Route(p2, p1));
+	public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
+		List<Point> p = routes.get(new Route(p1, p2));
+		if(p != null)
+			return p;
+		else return routes.get(new Route(p2, p1));
 	}
 	
 	public boolean canTakeRoute(List<Point> route, TreeSet<Character> keys) {
@@ -187,7 +189,7 @@ public boolean canTakeRoute(List<Point> route, TreeSet<Character> keys) {
 	
 	//int lowest = Integer.MAX_VALUE;
 	Map<State, Integer> cachedResult = new HashMap<>();
-	public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Point> keys) {
+	public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
 		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
 		if(cachedRes!=null)
 			return cachedRes;
@@ -197,8 +199,8 @@ public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Poin
 		} else if(currentSteps>=lowest) {
 			return currentSteps;
 		}*/
-		List<List<Point>> possibleMoves = me.stream().flatMap(m -> keys.stream().map(p -> charGrid.findPath(m, p))).filter(e -> !e.isEmpty()).collect(Collectors.toList());//keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
-		System.out.println(Arrays.toString(collectedKeys.toArray())+possibleMoves.size());
+		List<List<Point>> possibleMoves = me.stream().flatMap(m -> keys.stream().map(p -> getRoute(routes, m, p))).filter(Objects::nonNull).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());//keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
+		//System.out.println(Arrays.toString(collectedKeys.toArray())+possibleMoves.size());
 		//System.out.println("moves "+possibleMoves.size());
 		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
 		//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
@@ -210,7 +212,8 @@ public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Poin
 			//me = takenMove.get(takenMove.size()-1);
 			TreeSet<Character> myKeys = new TreeSet<>(collectedKeys);
 			List<Point> keyLocs = new ArrayList<>(keys);
-			Point newLoc = takenMove.get(takenMove.size()-1);
+			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];
 			//System.out.println((takenMove.size()-1)+" steps to "+collected);
 			myKeys.add(Character.toUpperCase(collected));
@@ -218,11 +221,11 @@ public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Poin
 				//doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
 			keyLocs.remove(newLoc);
 			List<Point> me2 = new ArrayList<>(me);
-			me2.set(me.indexOf(takenMove.get(0)), newLoc);
+			me2.set(me.indexOf(oldLoc), newLoc);
 			//System.out.println(collected);
 			//grid[newLoc.y][newLoc.x] = '@';
 			//System.out.println("Taken move "+collected+" for "+(takenMove.size()-1));
-			nSteps.add(findSteps(me2, myKeys, keyLocs) + takenMove.size()-1);
+			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);
@@ -253,6 +256,12 @@ private List<Point> findPos(char tile, char tile2) {
 	
 	@Override
 	public Object part2() throws IOException {
-		return 0;
+		for(int y = 0; y<CHANGE_GRID.length; y++) {
+			for(int x = 0; x<CHANGE_GRID[y].length; x++) {
+				grid[middle.y-1+y][middle.x-1+x] = CHANGE_GRID[y][x];
+			}
+		}
+		cachedResult.clear();
+		return findRoutes(findPos('@'));
 	}
 }

From 1b4b059b8b2465b974cffb68fd3de450abd8c9fd Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 19:56:14 +0100
Subject: [PATCH 103/120] Refactor Day 18

---
 .../sbaars/adventofcode2019/days/Day18.java   | 142 ++----------------
 1 file changed, 9 insertions(+), 133 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index d4eb965b..6dd4cd0b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -14,6 +14,8 @@
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.pathfinding.CharGrid2d;
 
+import lombok.*;
+
 public class Day18 implements Day {
 	
 	private final char[][] grid;
@@ -35,89 +37,14 @@ public static void main(String[] args) throws IOException {
 		new Day18().printParts();
 	}
 	
-	class Route {
+	@Data @AllArgsConstructor class Route {
 		Point start;
 		Point end;
-		@Override
-		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result + ((end == null) ? 0 : end.hashCode());
-			result = prime * result + ((start == null) ? 0 : start.hashCode());
-			return result;
-		}
-		public Route(Point start, Point end) {
-			super();
-			this.start = start;
-			this.end = end;
-		}
-		@Override
-		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
-				return false;
-			if (getClass() != obj.getClass())
-				return false;
-			Route other = (Route) obj;
-			if (end == null) {
-				if (other.end != null)
-					return false;
-			} else if (!end.equals(other.end))
-				return false;
-			if (start == null) {
-				if (other.start != null)
-					return false;
-			} else if (!start.equals(other.start))
-				return false;
-			return true;
-		}
-		@Override
-		public String toString() {
-			return "Route [start=" + start + ", end=" + end + "]";
-		}
-		
-		
 	}
 	
-	class State{
+	@Data @AllArgsConstructor class State{
 		List<Point> me;
 		TreeSet<Character> keys;
-		public State(List<Point> me, TreeSet<Character> keys) {
-			super();
-			this.me = me;
-			this.keys = keys;
-		}
-		@Override
-		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result + ((keys == null) ? 0 : keys.hashCode());
-			result = prime * result + ((me == null) ? 0 : me.hashCode());
-			return result;
-		}
-		@Override
-		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
-				return false;
-			if (getClass() != obj.getClass())
-				return false;
-			State other = (State) obj;
-			if (keys == null) {
-				if (other.keys != null)
-					return false;
-			} else if (!keys.equals(other.keys))
-				return false;
-			if (me == null) {
-				if (other.me != null)
-					return false;
-			} else if (!me.equals(other.me))
-				return false;
-			return true;
-		}
-		
 	}
 
 	@Override
@@ -128,8 +55,6 @@ public Object part1() throws IOException {
 	}
 
 	private Object findRoutes(List<Point> me) {
-		//List<Character> collectedKeys = new ArrayList<>();
-		//int keysToCollect = findPos('a', 'z').size();
 		List<Point> keys = findPos('a', 'z');
 		Map<Route, List<Point>> routes = new HashMap<>();
 		List<Point> requiredRoutes = new ArrayList<>(keys);
@@ -141,33 +66,6 @@ private Object findRoutes(List<Point> me) {
 					routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
 			}
 		}
-		//List<Point> doors = findPos('A', 'Z');
-		/*int steps = 0;
-		//while(collectedKeys.size()<keysToCollect) {
-			//System.out.println("Keys = "+Arrays.toString(collectedKeys.toArray()));
-			//Arrays.stream(grid).map(e -> new String(e)).forEach(System.out::println);
-			final Point meNow = me;
-			List<List<Point>> possibleMoves = keys.stream().map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList());
-			//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
-			//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
-			List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
-			steps += takenMove.size()-1;
-			grid[me.y][me.x] = '.';
-			me = takenMove.get(takenMove.size()-1);
-			char collected = grid[me.y][me.x];
-			//System.out.println((takenMove.size()-1)+" steps to "+collected);
-			if(collected >= 'a' && collected <= 'z') {
-				collectedKeys.add(Character.toUpperCase(collected));
-				doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
-				doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
-				keys.remove(me);
-			} 
-			grid[me.y][me.x] = '@';
-		//}
-		if(steps<5992)
-		System.out.println(steps);
-		}*/
-		//System.out.println(Arrays.toString(reachableKeys.toArray()));
 		return findSteps(me, new TreeSet<>(), keys, routes);
 	}
 	
@@ -187,44 +85,22 @@ public boolean canTakeRoute(List<Point> route, TreeSet<Character> keys) {
 		return true;
 	}
 	
-	//int lowest = Integer.MAX_VALUE;
 	Map<State, Integer> cachedResult = new HashMap<>();
 	public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
 		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
-		if(cachedRes!=null)
-			return cachedRes;
-		/*if(keys.isEmpty() && currentSteps<lowest) {
-			lowest = currentSteps;
-			System.out.println(lowest);
-		} else if(currentSteps>=lowest) {
-			return currentSteps;
-		}*/
-		List<List<Point>> possibleMoves = me.stream().flatMap(m -> keys.stream().map(p -> getRoute(routes, m, p))).filter(Objects::nonNull).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());//keys.stream().map(e -> getRoute(routes, me, e)).filter(e -> canTakeRoute(e, collectedKeys)).collect(Collectors.toList());
-		//System.out.println(Arrays.toString(collectedKeys.toArray())+possibleMoves.size());
-		//System.out.println("moves "+possibleMoves.size());
-		//possibleMoves.addAll(doors.stream().filter(e -> collectedKeys.contains(grid[e.y][e.x])).map(e -> charGrid.findPath(meNow, e)).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
-		//List<Point> takenMove = possibleMoves.stream().reduce((a, b) -> a.size()<b.size() ? a : b).get();
-		//System.out.println(possibleMoves.size()+", "+collectedKeys.size());
+		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<Integer> nSteps = new ArrayList<>();
 		for(List<Point> takenMove : possibleMoves) {
-		//List<Point> takenMove = possibleMoves.get(new Random().nextInt(possibleMoves.size()));
-			//grid[me.y][me.x] = '.';
-			//me = takenMove.get(takenMove.size()-1);
-			TreeSet<Character> myKeys = new TreeSet<>(collectedKeys);
-			List<Point> keyLocs = new ArrayList<>(keys);
+			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];
-			//System.out.println((takenMove.size()-1)+" steps to "+collected);
 			myKeys.add(Character.toUpperCase(collected));
-				//doors.stream().filter(e -> grid[e.y][e.x] == Character.toUpperCase(collected)).forEach(e -> grid[e.y][e.x] = '.');
-				//doors.removeIf(e -> grid[e.y][e.x] == Character.toUpperCase(collected));
 			keyLocs.remove(newLoc);
-			List<Point> me2 = new ArrayList<>(me);
+			val me2 = new ArrayList<>(me);
 			me2.set(me.indexOf(oldLoc), newLoc);
-			//System.out.println(collected);
-			//grid[newLoc.y][newLoc.x] = '@';
-			//System.out.println("Taken move "+collected+" for "+(takenMove.size()-1));
 			nSteps.add(findSteps(me2, myKeys, keyLocs, routes) + takenMove.size()-1);
 		}
 		int res = nSteps.stream().mapToInt(e -> e).min().orElse(0);

From 57bc27809e36a076f95516d647431efd30f149e0 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 20:16:09 +0100
Subject: [PATCH 104/120] Refactor days

---
 .../sbaars/adventofcode2019/days/Day10.java   | 24 ++----
 .../sbaars/adventofcode2019/days/Day12.java   |  3 +-
 .../sbaars/adventofcode2019/days/Day17.java   | 29 +------
 .../sbaars/adventofcode2019/days/Day2.java    | 10 +--
 .../sbaars/adventofcode2019/days/Day3.java    | 20 ++---
 .../sbaars/adventofcode2019/days/Day6.java    | 12 +--
 .../sbaars/adventofcode2019/days/Day7.java    |  4 +-
 .../sbaars/adventofcode2019/days/Day8.java    |  4 +-
 .../pathfinding/CharGrid2d.java               |  2 +-
 .../adventofcode2019/pathfinding/Example.java | 77 -------------------
 .../sbaars/adventofcode2019/util/Pair.java    | 12 ---
 11 files changed, 27 insertions(+), 170 deletions(-)
 delete mode 100644 src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
 delete mode 100644 src/main/java/com/sbaars/adventofcode2019/util/Pair.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
index 712aa57d..226b165c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day10.java
@@ -10,6 +10,8 @@
 
 import com.sbaars.adventofcode2019.common.Day;
 
+import lombok.EqualsAndHashCode;
+
 public class Day10 implements Day {
 	
 	private final List<Point> asteroids;
@@ -52,9 +54,9 @@ private long countNVisible(Point asteroid) {
 		return asteroids.stream().map(e -> new Asteroid(asteroid, e)).mapToDouble(e -> e.rotation).distinct().count();
 	}
 	
-	class Asteroid {
-		double rotation;
-		double distance;
+	@EqualsAndHashCode class Asteroid {
+		@EqualsAndHashCode.Exclude double rotation;
+		@EqualsAndHashCode.Exclude double distance;
 		Point position;
 		
 		public Asteroid(Point center, Point me) {
@@ -72,21 +74,5 @@ private double calcRotationAngleInDegrees(Point centerPt, Point targetPt) {
 		    double angle = Math.toDegrees(theta);
 		    return angle < 0 ? angle + 360 : angle;
 		}
-
-		@Override
-		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result + ((position == null) ? 0 : position.hashCode());
-			return result;
-		}
-
-		@Override
-		public boolean equals(Object obj) {
-			if (!(obj instanceof Asteroid))
-				return false;
-			Asteroid other = (Asteroid) obj;
-			return position.equals(other.position);
-		}
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
index 50a92bbf..2d269051 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day12.java
@@ -74,8 +74,7 @@ private void determineVelocity() {
 	}
 	
 	private static long gcd(long a, long b) {
-	    while (b > 0)
-	    {
+	    while (b > 0) {
 	        long temp = b;
 	        b = a % b; // % is remainder
 	        a = temp;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
index d205dcb0..9b180a8b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -11,6 +11,8 @@
 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];
@@ -141,7 +143,7 @@ private List<Point> findPos(char[][] grid, char tile) {
 	}
 
 	enum Dir{L,R}
-	class Instruction{
+	@EqualsAndHashCode class Instruction{
 		int amount;
 		Dir dir;
 
@@ -155,30 +157,5 @@ public Instruction(int amount, Dir dir) {
 		public String toString() {
 			return dir.name()+","+amount;
 		}
-
-		@Override
-		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result + amount;
-			result = prime * result + ((dir == null) ? 0 : dir.hashCode());
-			return result;
-		}
-
-		@Override
-		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
-				return false;
-			if (getClass() != obj.getClass())
-				return false;
-			Instruction other = (Instruction) obj;
-			if (amount != other.amount)
-				return false;
-			if (dir != other.dir)
-				return false;
-			return true;
-		}
 	}
 }
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
index 2f17263c..fea0cc37 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day2.java
@@ -10,12 +10,12 @@ public class Day2 implements Day {
 	public static void main(String[] args) throws IOException {
 		new Day2().printParts();
 	}
-	
+
 	@Override
 	public Object part1() throws IOException {
 		return execute(12,2);
 	}
-	
+
 	@Override 
 	public Object part2() throws IOException {
 		return bruteForceFindingNumber(19690720, 99);
@@ -24,10 +24,10 @@ public Object part2() throws IOException {
 	private int bruteForceFindingNumber(int number, int bound) throws IOException {
 		for(int i = 0; i<bound;i++) {
 			for(int j = 0; j<bound; j++) {
-					if(execute(i, j) == number) {
-						return 100 * i + j;
-					}
+				if(execute(i, j) == number) {
+					return 100 * i + j;
 				}
+			}
 		}
 		return -1;
 	}
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
index 267d2895..27b93927 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day3.java
@@ -9,6 +9,8 @@
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.common.Direction;
 
+import lombok.EqualsAndHashCode;
+
 public class Day3 implements Day
 {	
 	private Set<Step> intersect;
@@ -84,27 +86,15 @@ public Walk(String code) {
 		}
 	}
 	
-	class Step {
+	@EqualsAndHashCode class Step {
 		private final Point point;
-		private int steps;
-		private boolean isCombined = false;
+		@EqualsAndHashCode.Exclude private int steps;
+		@EqualsAndHashCode.Exclude private boolean isCombined = false;
 		
 		public Step(Point point, int steps) {
 			this.point = point;
 			this.steps = steps + 1;
 		}
-
-		@Override
-		public int hashCode() {
-			return 31 + ((point == null) ? 0 : point.hashCode());
-		}
-
-		@Override
-		public boolean equals(Object obj) {
-			if (!(obj instanceof Step))
-				return false;
-			return point.equals(((Step) obj).point);
-		}
 		
 		public void combine(Step step) {
 			if(!isCombined) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
index 50813c0e..9a31e4ba 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day6.java
@@ -4,8 +4,8 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.util.ListMap;
@@ -27,7 +27,7 @@ public Object part1() throws IOException {
     		orbits.addTo(parts[0], parts[1]);
     	}
     	AtomicInteger o = new AtomicInteger();
-    	for(Entry<String, List<String>> entry : orbits.entrySet())
+    	for(var entry : orbits.entrySet())
     		countOrbitsInList(orbits, o, entry.getValue());
 		return o.get();
 	}
@@ -71,13 +71,7 @@ private List<String> collectAll(String s1) {
 	}
 
 	public List<String> findOrbit(String orbitValue) {
-		List<String> orbit = new ArrayList<>();
-    	for(Entry<String, List<String>> entry : orbits.entrySet()) {
-    		if(entry.getValue().contains(orbitValue)) {
-    			orbit.add(entry.getKey());
-    		}
-    	}
-    	return orbit;
+		return orbits.entrySet().stream().filter(e -> e.getValue().contains(orbitValue)).map(e -> e.getKey()).collect(Collectors.toList());
     }
 
 	private String[] createOrbitArray() throws IOException {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
index 46c0248c..433af6b0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day7.java
@@ -16,7 +16,7 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public Object part1() throws IOException {
-		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
+		var permutations = generatePerm(new ArrayList<>(Arrays.asList(0,1,2,3,4)));
 		List<Long> results = new ArrayList<>();
 		for(List<Integer> perm : permutations) {
 			long lastVal = 0;
@@ -30,7 +30,7 @@ public Object part1() throws IOException {
 
 	@Override
 	public Object part2() throws IOException {
-		List<List<Integer>> permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
+		var permutations = generatePerm(new ArrayList<>(Arrays.asList(5,6,7,8,9)));
 		List<Long> results = new ArrayList<>();
 		perms: for(List<Integer> shuffle : permutations) {
 			IntcodeComputer[] computers = new IntcodeComputer[5];
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
index 4887d8d8..c53be49f 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day8.java
@@ -22,8 +22,8 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		int[] pixels = readPixels();
-		List<CountMap<Integer>> pixelCounts = countPixels(pixels);
-		CountMap<Integer> cm = pixelCounts.stream().reduce((e1, e2) -> e1.get(0) > e2.get(0) ? e2 : e1).get();
+		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);
 	}
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
index 929326ef..842824b3 100644
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
+++ b/src/main/java/com/sbaars/adventofcode2019/pathfinding/CharGrid2d.java
@@ -66,7 +66,7 @@ public Set<MapNode> getNeighbours() {
 						continue;
 					}
 
-					if (map[j][i] == '#'/* || (map[j][i]>='A' && map[j][i]<='Z' && !collectedKeys.contains(map[j][i]))*/) {
+					if (map[j][i] == '#') {
 						continue;
 					}
 
diff --git a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java b/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
deleted file mode 100644
index cccb1cfc..00000000
--- a/src/main/java/com/sbaars/adventofcode2019/pathfinding/Example.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.sbaars.adventofcode2019.pathfinding;
-
-import java.awt.Point;
-import java.util.Arrays;
-import java.util.List;
-
-import com.sbaars.adventofcode2019.common.Direction;
-
-public class Example {
-	
-	static int[][] grid = {{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 1, 1, 1, 0, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 1, 0, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 0, 0, 1, 0, 1, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 0, 1, 1, 1, 0, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 1, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
-	{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}};
-
-	public static void main(String[] args) {
-		Grid2d map2d = new Grid2d(grid, false);
-		Point start = new Point(7,27);
-		Point end = new Point(14,27);
-		grid[start.y][start.x] = 8;
-		List<Point> route = map2d.findPath(start, end);
-		System.out.println("Go from "+start+" to "+end+" by route "+route.subList(1, route.size()));
-		route.subList(1, route.size()).stream().forEach(p -> grid[p.y][p.x] = 9);//.peek(System.out::println);
-		for(Point p : route.subList(1, route.size())) {
-			System.out.println("Dir "+Direction.getByMove(start, p));
-			start = p;
-		}
-		Arrays.stream(grid).map(e -> Arrays.toString(e)).forEach(System.out::println);
-	}
-
-}
diff --git a/src/main/java/com/sbaars/adventofcode2019/util/Pair.java b/src/main/java/com/sbaars/adventofcode2019/util/Pair.java
deleted file mode 100644
index d07dbc5f..00000000
--- a/src/main/java/com/sbaars/adventofcode2019/util/Pair.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.sbaars.adventofcode2019.util;
-
-public class Pair<K, V> {
-	public final K fst;
-	public final V snd;
-	
-	public Pair(K key, V value) {
-		super();
-		this.fst = key;
-		this.snd = value;
-	}
-}

From 80feb7d34d6ffe614cf97d9bb9dcdbee74585364 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Wed, 18 Dec 2019 20:17:52 +0100
Subject: [PATCH 105/120] Added day 18 to README

---
 README.md                                           | 5 +++++
 src/main/java/com/sbaars/adventofcode2019/Main.java | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index ae02bed5..82baf5d7 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ Days:
 - [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)
 
 Output of running [Main.java](https://github.com/SimonBaars/adventOfCode-2019/blob/master/src/main/java/com/sbaars/adventofcode2019/Main.java):
 ```
@@ -101,4 +102,8 @@ Part 2: 62858988
 Day 17:
 Part 1: 7404
 Part 2: 929045
+
+Day 18:
+Part 1: 5402
+Part 2: 2138
 ```
\ No newline at end of file
diff --git a/src/main/java/com/sbaars/adventofcode2019/Main.java b/src/main/java/com/sbaars/adventofcode2019/Main.java
index 5e7a3622..da3c23a0 100644
--- a/src/main/java/com/sbaars/adventofcode2019/Main.java
+++ b/src/main/java/com/sbaars/adventofcode2019/Main.java
@@ -7,7 +7,7 @@
 
 public class Main {
 	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException, InvocationTargetException, NoSuchMethodException {
-		for(int day = 1; day<=17; day++) {
+		for(int day = 1; day<=18; day++) {
 			System.out.println("Day "+day+":");
 			Day instance = (Day)Class.forName("com.sbaars.adventofcode2019.days.Day"+day).getDeclaredConstructor().newInstance();
 			instance.printParts();

From 738c20e84e9c2e838597b161d4e05ebe26e28c19 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 19 Dec 2019 06:51:17 +0100
Subject: [PATCH 106/120] Day 19

Finally a relatively easy one again
---
 .../sbaars/adventofcode2019/days/Day19.java   | 45 +++++++++++++++++++
 .../intcode/IntcodeComputer.java              |  2 +-
 src/main/resources/day19.txt                  |  6 +--
 3 files changed, 47 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day19.java

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day19.java b/src/main/java/com/sbaars/adventofcode2019/days/Day19.java
new file mode 100644
index 00000000..f8d25001
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day19.java
@@ -0,0 +1,45 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day19 implements Day {
+
+	public static void main(String[] args) throws IOException {
+		new Day19().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		/*for(int i = 0; i<200;i++) {
+			for(int j = 0; j<100;j++) {
+				System.out.print(new IntcodeComputer(19, 1).run(i, j));
+			}
+			System.out.println();
+		}*/
+		long res = 0;
+		for(int x = 0; x<50;x++) {
+			for(int y = 0; y<50;y++) {
+				res+=new IntcodeComputer(19).run(x, y);
+			}
+		}
+		return res;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		int x = 500, y = 0;
+		while(true) {
+			if(beam(x, y)) {
+				if(beam(x-99, y+99)) return 10000 * (x - 99) + y;
+				x++;
+			} else y++;
+		}
+	}
+
+	private boolean beam(int x, int y) throws IOException {
+		return new IntcodeComputer(19).run(x, y) == 1L;
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 430f373b..1100ec10 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -31,7 +31,7 @@ public IntcodeComputer(int day, long...input) throws IOException {
 		}
 	}
 	
-	public long run(long input) {
+	public long run(long...input) {
 		setInput(input);
 		return run();
 	}
diff --git a/src/main/resources/day19.txt b/src/main/resources/day19.txt
index 7345fa09..4bdbeb34 100644
--- a/src/main/resources/day19.txt
+++ b/src/main/resources/day19.txt
@@ -1,5 +1 @@
-########################
-#f.D.E.e.C.b.A.@.a.B.c.#
-######################.#
-#d.....................#
-########################
\ No newline at end of file
+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

From ebb0c64a91c63cd4a74d04aa663d5d68d775570e Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 19 Dec 2019 06:58:37 +0100
Subject: [PATCH 107/120] Refactor day 19

---
 .../com/sbaars/adventofcode2019/days/Day19.java    | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day19.java b/src/main/java/com/sbaars/adventofcode2019/days/Day19.java
index f8d25001..ce2485ca 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day19.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day19.java
@@ -13,18 +13,10 @@ public static void main(String[] args) throws IOException {
 
 	@Override
 	public Object part1() throws IOException {
-		/*for(int i = 0; i<200;i++) {
-			for(int j = 0; j<100;j++) {
-				System.out.print(new IntcodeComputer(19, 1).run(i, j));
-			}
-			System.out.println();
-		}*/
 		long res = 0;
-		for(int x = 0; x<50;x++) {
-			for(int y = 0; y<50;y++) {
+		for(int x = 0; x<50;x++) 
+			for(int y = 0; y<50;y++) 
 				res+=new IntcodeComputer(19).run(x, y);
-			}
-		}
 		return res;
 	}
 	
@@ -34,7 +26,7 @@ public Object part2() throws IOException {
 		while(true) {
 			if(beam(x, y)) {
 				if(beam(x-99, y+99)) return 10000 * (x - 99) + y;
-				x++;
+				else x++;
 			} else y++;
 		}
 	}

From 684d7b93cf14446a5a841d7c654ac94c0ec69f5b Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Thu, 19 Dec 2019 07:00:03 +0100
Subject: [PATCH 108/120] Add day 19 to README

---
 README.md                                           | 5 +++++
 src/main/java/com/sbaars/adventofcode2019/Main.java | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 82baf5d7..1b4cf67c 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ Days:
 - [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):
 ```
@@ -106,4 +107,8 @@ 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/src/main/java/com/sbaars/adventofcode2019/Main.java b/src/main/java/com/sbaars/adventofcode2019/Main.java
index da3c23a0..745d7c0d 100644
--- a/src/main/java/com/sbaars/adventofcode2019/Main.java
+++ b/src/main/java/com/sbaars/adventofcode2019/Main.java
@@ -7,7 +7,7 @@
 
 public class Main {
 	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException, InvocationTargetException, NoSuchMethodException {
-		for(int day = 1; day<=18; day++) {
+		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();

From 122e9a25fd6ac9441608d3eabffa05d59e9efe2a Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 20 Dec 2019 07:39:08 +0100
Subject: [PATCH 109/120] Day 20 Part 1

---
 .../sbaars/adventofcode2019/days/Day20.java   | 182 ++++++++++++++++++
 src/main/resources/day20.txt                  | 107 ++++++++++
 2 files changed, 289 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day20.java
 create mode 100644 src/main/resources/day20.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
new file mode 100644
index 00000000..57fbccf4
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -0,0 +1,182 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.pathfinding.CharGrid2d;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.val;
+
+public class Day20 implements Day {
+	char[][] grid;
+	CharGrid2d charGrid;
+	
+	public Day20() throws IOException {
+		grid = Arrays.stream(readDay(20).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
+		charGrid = new CharGrid2d(grid, false);
+	}
+
+	public static void main(String[] args) throws IOException {
+		new Day20().printParts();
+	}
+	
+	@Data @AllArgsConstructor class Portal {
+		String value;
+		Point location;
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		Arrays.stream(grid).forEach(e -> System.out.println(new String(e)));
+		int[] rows = {2, 26, 80, 104};
+		List<Portal> portals = new ArrayList<>();
+		for(int row : rows) {
+			for(int i = 2; i<grid.length-2; i++) {
+				//System.out.println(row+", "+i+", "+grid[i][row]+", "+grid[i][row-1]);
+				if(grid[i][row] == '.') {
+					if(Character.isAlphabetic(grid[i][row-1])) {
+						portals.add(new Portal(""+grid[i][row-2]+grid[i][row-1], new Point(row, i)));
+					} else if (Character.isAlphabetic(grid[i][row+1])) {
+						portals.add(new Portal(""+grid[i][row+2]+grid[i][row+1], new Point(row, i)));
+					}
+				}
+				if(grid[row][i] == '.') {
+					if(Character.isAlphabetic(grid[row-1][i])) {
+						portals.add(new Portal(""+grid[row-2][i]+grid[row-1][i], new Point(i, row)));
+					} else if (Character.isAlphabetic(grid[row+1][i])) {
+						portals.add(new Portal(""+grid[row+1][i]+grid[row+2][i], new Point(i, row)));
+					}
+				}
+			}
+		}
+		return findRoutes(getPortal(portals, "AA").stream().map(e -> e.location).findAny().get(), portals);
+		//System.out.println(Arrays.toString(portals.toArray()));
+		//return 0;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		return 0;
+	}
+	
+	@Data @AllArgsConstructor class Route {
+		Point start;
+		Point end;
+	}
+	
+	@Data @AllArgsConstructor class State{
+		Point me;
+		TreeSet<String> portalsTaken;
+	}
+	
+	private Object findRoutes(Point me, List<Portal> portals) {
+		Map<Route, List<Point>> routes = new HashMap<>();
+		List<Point> requiredRoutes = new ArrayList<>(portals.stream().map(e -> e.location).collect(Collectors.toList()));
+		requiredRoutes.add(me);
+		for(int i = 0; i<requiredRoutes.size(); i++) {
+			for(int j = i+1; j<requiredRoutes.size(); j++) {
+				List<Point> r = charGrid.findPath(requiredRoutes.get(i), requiredRoutes.get(j));
+				if(!r.isEmpty())
+					routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
+			}
+		}
+		removePortal(portals, "AA");
+		return findSteps(me, new TreeSet<>(), portals, routes);
+	}
+	
+	public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
+		List<Point> p = routes.get(new Route(p1, p2));
+		if(p != null) return p;
+		else return routes.get(new Route(p2, p1));
+	}
+	
+	public boolean canTakeRoute(List<Point> route, TreeSet<Character> 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;
+	}
+	
+	Map<State, Integer> cachedResult = new HashMap<>();
+	public int findSteps(Point me, TreeSet<String> collectedKeys, List<Portal> portals, Map<Route, List<Point>> routes) {
+		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
+		if(cachedRes!=null) return cachedRes;
+		
+		var possibleMoves = portals.stream().filter(p -> !collectedKeys.contains(p.value)).map(p -> getRoute(routes, me, p.location)).filter(Objects::nonNull).collect(Collectors.toList());
+		removeDuplicates(me, portals, possibleMoves);
+		
+		List<Integer> nSteps = new ArrayList<>();
+		for(List<Point> takenMove : possibleMoves) {
+			Point moveTo = me.equals(takenMove.get(0)) ? takenMove.get(takenMove.size()-1) : takenMove.get(0);
+			Portal thisPortal = getPortal(portals, moveTo);
+			if(thisPortal.value.equals("ZZ")) {
+				nSteps.add(takenMove.size()-1);
+				continue;
+			}
+			
+			List<Portal> teleport = getPortal(portals, thisPortal.value);
+			Point newLoc = null;
+			for(Portal portal : teleport) {
+				if(!portal.location.equals(moveTo)) {
+					newLoc = portal.getLocation();
+				}
+			}
+			val myKeys = new TreeSet<>(collectedKeys);
+			val keyLocs = new ArrayList<>(portals);
+			//Point newLoc = me.contains(takenMove.get(0)) ? moveTo : takenMove.get(0);
+			//Point oldLoc = me.equals(takenMove.get(0)) ? takenMove.get(0) : moveTo;
+			myKeys.add(thisPortal.value);
+			keyLocs.removeAll(teleport);
+			nSteps.add(findSteps(newLoc, 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 void removeDuplicates(Point me, List<Portal> portals, List<List<Point>> possibleMoves) {
+		Map<Point, Integer> pointIndices = new HashMap<>();
+		for(int i = 0; i<possibleMoves.size(); i++) {
+			Point moveTo = me.equals(possibleMoves.get(i).get(0)) ? possibleMoves.get(i).get(possibleMoves.get(i).size()-1) : possibleMoves.get(i).get(0);
+			Portal p = getPortal(portals, moveTo);
+			List<Portal> ps = getPortal(portals, p.value);
+			for(Portal por : ps) {
+				Point portal = por.location;
+				if(!portal.equals(moveTo) && pointIndices.containsKey(portal)) {
+					int moves = possibleMoves.get(i).size();
+					int otherMoves = possibleMoves.get(pointIndices.get(portal)).size();
+					if(moves > otherMoves)
+						possibleMoves.remove(i);
+					else possibleMoves.remove(pointIndices.get(portal).intValue());
+				}
+			}
+			pointIndices.put(moveTo, 0);
+		}
+		
+	}
+
+	public List<Portal> getPortal(List<Portal> portals, String key){
+		return portals.stream().filter(e -> e.value.equals(key)).collect(Collectors.toList());
+	}
+	
+	public boolean removePortal(List<Portal> portals, String key){
+		return portals.removeIf(e -> e.value.equals(key));
+	}
+	
+	public Portal getPortal(List<Portal> portals, Point key){
+		return portals.stream().filter(e -> e.location.equals(key)).findAny().get();
+	}
+}
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

From 8c0311e64c33e7a5aae7528006dc3a6a93bc8ffa Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 20 Dec 2019 08:51:55 +0100
Subject: [PATCH 110/120] Start rewriting day 20

---
 src/main/java/com/sbaars/adventofcode2019/days/Day20.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index 57fbccf4..b7cea5fd 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -117,6 +117,8 @@ public int findSteps(Point me, TreeSet<String> collectedKeys, List<Portal> porta
 		
 		var possibleMoves = portals.stream().filter(p -> !collectedKeys.contains(p.value)).map(p -> getRoute(routes, me, p.location)).filter(Objects::nonNull).collect(Collectors.toList());
 		removeDuplicates(me, portals, possibleMoves);
+		if(collectedKeys.size()>3) possibleMoves.clear();
+		System.out.println(Arrays.toString(collectedKeys.toArray())+possibleMoves.size());
 		
 		List<Integer> nSteps = new ArrayList<>();
 		for(List<Point> takenMove : possibleMoves) {
@@ -142,7 +144,7 @@ public int findSteps(Point me, TreeSet<String> collectedKeys, List<Portal> porta
 			keyLocs.removeAll(teleport);
 			nSteps.add(findSteps(newLoc, myKeys, keyLocs, routes) + takenMove.size()-1);
 		}
-		int res = nSteps.stream().mapToInt(e -> e).min().orElse(0);
+		int res = nSteps.stream().mapToInt(e -> e).min().orElse(Integer.MAX_VALUE-10000);
 		cachedResult.put(new State(me, collectedKeys), res);
 		return res;
 	}

From cc8f65fb99d443d5666b014bc9f1fe94cbf5d803 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 20 Dec 2019 11:07:44 +0100
Subject: [PATCH 111/120] Stuff

---
 .../sbaars/adventofcode2019/days/Day18.java   |  2 +-
 .../sbaars/adventofcode2019/days/Day20.java   | 57 ++++++++++++-------
 2 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
index 6dd4cd0b..34bd42a9 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day18.java
@@ -20,6 +20,7 @@ public class Day18 implements Day {
 	
 	private final char[][] grid;
 	private final CharGrid2d charGrid;
+	private final Map<State, Integer> cachedResult = new HashMap<>();
 	private static final char[][] CHANGE_GRID = {
 			{'@', '#', '@'},
 			{'#', '#', '#'},
@@ -85,7 +86,6 @@ public boolean canTakeRoute(List<Point> route, TreeSet<Character> keys) {
 		return true;
 	}
 	
-	Map<State, Integer> cachedResult = new HashMap<>();
 	public int findSteps(List<Point> me, TreeSet<Character> collectedKeys, List<Point> keys, Map<Route, List<Point>> routes) {
 		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
 		if(cachedRes!=null) return cachedRes;
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index b7cea5fd..a302a4f7 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -21,45 +21,57 @@
 public class Day20 implements Day {
 	char[][] grid;
 	CharGrid2d charGrid;
+	private final List<Portal> outerRing = new ArrayList<>();
+	private final List<Portal> innerRing = new ArrayList<>();
+	private Portal entry;
+	private Portal exit;
 	
 	public Day20() throws IOException {
 		grid = Arrays.stream(readDay(20).split(System.lineSeparator())).map(e -> e.toCharArray()).toArray(char[][]::new);
 		charGrid = new CharGrid2d(grid, false);
-	}
-
-	public static void main(String[] args) throws IOException {
-		new Day20().printParts();
-	}
-	
-	@Data @AllArgsConstructor class Portal {
-		String value;
-		Point location;
-	}
-
-	@Override
-	public Object part1() throws IOException {
-		Arrays.stream(grid).forEach(e -> System.out.println(new String(e)));
+		
 		int[] rows = {2, 26, 80, 104};
-		List<Portal> portals = new ArrayList<>();
 		for(int row : rows) {
+			boolean addPortal = row == rows[0] || row == rows[rows.length];
 			for(int i = 2; i<grid.length-2; i++) {
 				//System.out.println(row+", "+i+", "+grid[i][row]+", "+grid[i][row-1]);
 				if(grid[i][row] == '.') {
 					if(Character.isAlphabetic(grid[i][row-1])) {
-						portals.add(new Portal(""+grid[i][row-2]+grid[i][row-1], new Point(row, i)));
+						addPortal(new Portal(""+grid[i][row-2]+grid[i][row-1], new Point(row, i)), addPortal);
 					} else if (Character.isAlphabetic(grid[i][row+1])) {
-						portals.add(new Portal(""+grid[i][row+2]+grid[i][row+1], new Point(row, i)));
+						addPortal(new Portal(""+grid[i][row+2]+grid[i][row+1], new Point(row, i)), addPortal);
 					}
 				}
 				if(grid[row][i] == '.') {
 					if(Character.isAlphabetic(grid[row-1][i])) {
-						portals.add(new Portal(""+grid[row-2][i]+grid[row-1][i], new Point(i, row)));
+						addPortal(new Portal(""+grid[row-2][i]+grid[row-1][i], new Point(i, row)), addPortal);
 					} else if (Character.isAlphabetic(grid[row+1][i])) {
-						portals.add(new Portal(""+grid[row+1][i]+grid[row+2][i], new Point(i, row)));
+						addPortal(new Portal(""+grid[row+1][i]+grid[row+2][i], new Point(i, row)), addPortal);
 					}
 				}
 			}
 		}
+	}
+	
+	public void addPortal(Portal p, boolean outerRing) {
+		if(p.value.equals("AA")) this.entry = p;
+		else if(p.value.equals("AA")) this.exit = p;
+		else if(outerRing) this.outerRing.add(p);
+		else this.innerRing.add(p);
+	}
+
+	public static void main(String[] args) throws IOException {
+		new Day20().printParts();
+	}
+	
+	@Data @AllArgsConstructor class Portal {
+		String value;
+		Point location;
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		//Arrays.stream(grid).forEach(e -> System.out.println(new String(e)));
 		return findRoutes(getPortal(portals, "AA").stream().map(e -> e.location).findAny().get(), portals);
 		//System.out.println(Arrays.toString(portals.toArray()));
 		//return 0;
@@ -73,11 +85,16 @@ public Object part2() throws IOException {
 	@Data @AllArgsConstructor class Route {
 		Point start;
 		Point end;
+		List<Point> route;
+		
+		public int steps() {
+			return route.size();
+		}
 	}
 	
 	@Data @AllArgsConstructor class State{
 		Point me;
-		TreeSet<String> portalsTaken;
+		int depth;
 	}
 	
 	private Object findRoutes(Point me, List<Portal> portals) {

From 827e196a56862bd9eb2f1b46aaaa3e582aaa875e Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 20 Dec 2019 20:40:05 +0100
Subject: [PATCH 112/120] Different approach

---
 .../sbaars/adventofcode2019/days/Day20.java   | 237 ++++++++----------
 1 file changed, 101 insertions(+), 136 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index a302a4f7..c8040ed7 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -2,200 +2,165 @@
 
 import java.awt.Point;
 import java.io.IOException;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import java.util.TreeSet;
-import java.util.stream.Collectors;
+import java.util.Queue;
+import java.util.Set;
 
 import com.sbaars.adventofcode2019.common.Day;
 import com.sbaars.adventofcode2019.pathfinding.CharGrid2d;
+import com.sbaars.adventofcode2019.util.ListMap;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.val;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
 
 public class Day20 implements Day {
 	char[][] grid;
 	CharGrid2d charGrid;
-	private final List<Portal> outerRing = new ArrayList<>();
-	private final List<Portal> innerRing = new ArrayList<>();
+	private final Map<String, Portal[]> portals = new HashMap<>();
+	private final Map<Portal, String> portalLabel = new HashMap<>();
+	private final ListMap<Portal, Route> routes = new ListMap<>();
+	private final List<Portal> 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];
+			boolean addPortal = row == rows[0] || row == rows[rows.length-1];
 			for(int i = 2; i<grid.length-2; i++) {
-				//System.out.println(row+", "+i+", "+grid[i][row]+", "+grid[i][row-1]);
 				if(grid[i][row] == '.') {
 					if(Character.isAlphabetic(grid[i][row-1])) {
-						addPortal(new Portal(""+grid[i][row-2]+grid[i][row-1], new Point(row, i)), addPortal);
+						addPortal(""+grid[i][row-2]+grid[i][row-1], new Point(row, i), addPortal);
+						grid[i][row-1]='#';
 					} else if (Character.isAlphabetic(grid[i][row+1])) {
-						addPortal(new Portal(""+grid[i][row+2]+grid[i][row+1], new Point(row, i)), addPortal);
+						addPortal(""+grid[i][row+1]+grid[i][row+2], new Point(row, i), addPortal);
+						grid[i][row+1]='#';
 					}
 				}
 				if(grid[row][i] == '.') {
 					if(Character.isAlphabetic(grid[row-1][i])) {
-						addPortal(new Portal(""+grid[row-2][i]+grid[row-1][i], new Point(i, row)), addPortal);
+						addPortal(""+grid[row-2][i]+grid[row-1][i], new Point(i, row), addPortal);
+						grid[row-1][i] = '#';
 					} else if (Character.isAlphabetic(grid[row+1][i])) {
-						addPortal(new Portal(""+grid[row+1][i]+grid[row+2][i], new Point(i, row)), addPortal);
+						addPortal(""+grid[row+1][i]+grid[row+2][i], new Point(i, row), addPortal);
+						grid[row+1][i] = '#';
 					}
 				}
 			}
 		}
+		portalsToTake.addAll(portalLabel.keySet());
+		portalsToTake.add(exit);
 	}
 	
-	public void addPortal(Portal p, boolean outerRing) {
-		if(p.value.equals("AA")) this.entry = p;
-		else if(p.value.equals("AA")) this.exit = p;
-		else if(outerRing) this.outerRing.add(p);
-		else this.innerRing.add(p);
+	public void addPortal(String label, Point pos, boolean outerRing) {
+		Portal p = new Portal(pos, outerRing);
+		if(label.equals("AA")) this.entry = p;
+		else if(label.equals("ZZ")) this.exit = p;
+		else {
+			Portal[] portal = portals.get(label);
+			if(portal == null) {
+				portals.put(label, new Portal[] {p, null});
+			} else portal[1] = p;
+			portalLabel.put(p, label);
+		}
+		
 	}
 
 	public static void main(String[] args) throws IOException {
 		new Day20().printParts();
 	}
-	
-	@Data @AllArgsConstructor class Portal {
-		String value;
-		Point location;
-	}
 
 	@Override
 	public Object part1() throws IOException {
-		//Arrays.stream(grid).forEach(e -> System.out.println(new String(e)));
-		return findRoutes(getPortal(portals, "AA").stream().map(e -> e.location).findAny().get(), portals);
-		//System.out.println(Arrays.toString(portals.toArray()));
-		//return 0;
-	}
-	
-	@Override
-	public Object part2() throws IOException {
-		return 0;
-	}
-	
-	@Data @AllArgsConstructor class Route {
-		Point start;
-		Point end;
-		List<Point> route;
-		
-		public int steps() {
-			return route.size();
-		}
-	}
-	
-	@Data @AllArgsConstructor class State{
-		Point me;
-		int depth;
+		return findRoutes(false);
 	}
 	
-	private Object findRoutes(Point me, List<Portal> portals) {
-		Map<Route, List<Point>> routes = new HashMap<>();
-		List<Point> requiredRoutes = new ArrayList<>(portals.stream().map(e -> e.location).collect(Collectors.toList()));
-		requiredRoutes.add(me);
-		for(int i = 0; i<requiredRoutes.size(); i++) {
-			for(int j = i+1; j<requiredRoutes.size(); j++) {
-				List<Point> r = charGrid.findPath(requiredRoutes.get(i), requiredRoutes.get(j));
-				if(!r.isEmpty())
-					routes.put(new Route(requiredRoutes.get(i), requiredRoutes.get(j)), r);
+	private int findRoutes(boolean b) {
+		final Queue<State> queue = new ArrayDeque<>();
+		final Set<Visited> visited = new HashSet<>();
+		queue.add(new State("", 0, new Visited(entry, 0)));
+		while(true) {
+			State s = queue.poll();
+			//System.out.println(Arrays.toString(queue.toArray()));
+			//System.out.println("------");
+			//System.out.println(s+", "+portalLabel.get(s.pos));
+			if(s.level == 0 && s.pos.equals(exit)) {
+				System.out.println(s.debug);
+				return s.totalSteps;
 			}
-		}
-		removePortal(portals, "AA");
-		return findSteps(me, new TreeSet<>(), portals, routes);
-	}
-	
-	public List<Point> getRoute(Map<Route, List<Point>> routes, Point p1, Point p2){
-		List<Point> p = routes.get(new Route(p1, p2));
-		if(p != null) return p;
-		else return routes.get(new Route(p2, p1));
-	}
-	
-	public boolean canTakeRoute(List<Point> route, TreeSet<Character> 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;
-	}
-	
-	Map<State, Integer> cachedResult = new HashMap<>();
-	public int findSteps(Point me, TreeSet<String> collectedKeys, List<Portal> portals, Map<Route, List<Point>> routes) {
-		Integer cachedRes = cachedResult.get(new State(me, collectedKeys));
-		if(cachedRes!=null) return cachedRes;
-		
-		var possibleMoves = portals.stream().filter(p -> !collectedKeys.contains(p.value)).map(p -> getRoute(routes, me, p.location)).filter(Objects::nonNull).collect(Collectors.toList());
-		removeDuplicates(me, portals, possibleMoves);
-		if(collectedKeys.size()>3) possibleMoves.clear();
-		System.out.println(Arrays.toString(collectedKeys.toArray())+possibleMoves.size());
-		
-		List<Integer> nSteps = new ArrayList<>();
-		for(List<Point> takenMove : possibleMoves) {
-			Point moveTo = me.equals(takenMove.get(0)) ? takenMove.get(takenMove.size()-1) : takenMove.get(0);
-			Portal thisPortal = getPortal(portals, moveTo);
-			if(thisPortal.value.equals("ZZ")) {
-				nSteps.add(takenMove.size()-1);
-				continue;
-			}
-			
-			List<Portal> teleport = getPortal(portals, thisPortal.value);
-			Point newLoc = null;
-			for(Portal portal : teleport) {
-				if(!portal.location.equals(moveTo)) {
-					newLoc = portal.getLocation();
+			else if(s.level < 0) continue;
+			if(!routes.containsKey(s.pos)) determineRoutes(s.pos);
+			for(Route route : routes.get(s.pos)) {
+				//System.out.println(route);
+				int level = s.level;
+				if(b) level+=route.goal.isOuter ? -1 : 1;
+				Visited vis = new Visited(route.goal, level);
+				if(!visited.contains(vis)) {
+					//System.out.println("ADD!");
+					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));
 				}
 			}
-			val myKeys = new TreeSet<>(collectedKeys);
-			val keyLocs = new ArrayList<>(portals);
-			//Point newLoc = me.contains(takenMove.get(0)) ? moveTo : takenMove.get(0);
-			//Point oldLoc = me.equals(takenMove.get(0)) ? takenMove.get(0) : moveTo;
-			myKeys.add(thisPortal.value);
-			keyLocs.removeAll(teleport);
-			nSteps.add(findSteps(newLoc, myKeys, keyLocs, routes) + takenMove.size()-1);
 		}
-		int res = nSteps.stream().mapToInt(e -> e).min().orElse(Integer.MAX_VALUE-10000);
-		cachedResult.put(new State(me, collectedKeys), res);
-		return res;
 	}
-	
-	private void removeDuplicates(Point me, List<Portal> portals, List<List<Point>> possibleMoves) {
-		Map<Point, Integer> pointIndices = new HashMap<>();
-		for(int i = 0; i<possibleMoves.size(); i++) {
-			Point moveTo = me.equals(possibleMoves.get(i).get(0)) ? possibleMoves.get(i).get(possibleMoves.get(i).size()-1) : possibleMoves.get(i).get(0);
-			Portal p = getPortal(portals, moveTo);
-			List<Portal> ps = getPortal(portals, p.value);
-			for(Portal por : ps) {
-				Point portal = por.location;
-				if(!portal.equals(moveTo) && pointIndices.containsKey(portal)) {
-					int moves = possibleMoves.get(i).size();
-					int otherMoves = possibleMoves.get(pointIndices.get(portal)).size();
-					if(moves > otherMoves)
-						possibleMoves.remove(i);
-					else possibleMoves.remove(pointIndices.get(portal).intValue());
-				}
+
+	private void determineRoutes(Portal p) {
+		for(Portal portal : portalsToTake) {
+			if(!portal.pos.equals(p.pos)) {
+				List<Point> route = charGrid.findPath(p.pos, portal.pos);
+				if(!route.isEmpty()) routes.addTo(p, new Route(teleport(portal), route.size()-1));
+				//System.out.println("portal from "+portal+portalLabel.get(portal)+" to "+routes.get(p).get(routes.get(p).size()-1));}
 			}
-			pointIndices.put(moveTo, 0);
 		}
-		
 	}
 
-	public List<Portal> getPortal(List<Portal> portals, String key){
-		return portals.stream().filter(e -> e.value.equals(key)).collect(Collectors.toList());
+	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];
 	}
-	
-	public boolean removePortal(List<Portal> portals, String key){
-		return portals.removeIf(e -> e.value.equals(key));
-	}
-	
-	public Portal getPortal(List<Portal> portals, Point key){
-		return portals.stream().filter(e -> e.location.equals(key)).findAny().get();
+
+	@Override
+	public Object part2() throws IOException {
+		return findRoutes(true);
 	}
 }

From aafea49622662e9a70e5b788ff1cc01b93775bb4 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Fri, 20 Dec 2019 20:58:52 +0100
Subject: [PATCH 113/120] Removed print stuff

---
 .../java/com/sbaars/adventofcode2019/days/Day20.java   | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index c8040ed7..363874a5 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -119,22 +119,17 @@ private int findRoutes(boolean b) {
 		queue.add(new State("", 0, new Visited(entry, 0)));
 		while(true) {
 			State s = queue.poll();
-			//System.out.println(Arrays.toString(queue.toArray()));
-			//System.out.println("------");
-			//System.out.println(s+", "+portalLabel.get(s.pos));
 			if(s.level == 0 && s.pos.equals(exit)) {
 				System.out.println(s.debug);
-				return s.totalSteps;
+				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)) {
-				//System.out.println(route);
 				int level = s.level;
 				if(b) level+=route.goal.isOuter ? -1 : 1;
 				Visited vis = new Visited(route.goal, level);
 				if(!visited.contains(vis)) {
-					//System.out.println("ADD!");
 					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));
 				}
@@ -146,8 +141,7 @@ private void determineRoutes(Portal p) {
 		for(Portal portal : portalsToTake) {
 			if(!portal.pos.equals(p.pos)) {
 				List<Point> route = charGrid.findPath(p.pos, portal.pos);
-				if(!route.isEmpty()) routes.addTo(p, new Route(teleport(portal), route.size()-1));
-				//System.out.println("portal from "+portal+portalLabel.get(portal)+" to "+routes.get(p).get(routes.get(p).size()-1));}
+				if(!route.isEmpty()) routes.addTo(p, new Route(teleport(portal), route.size()));
 			}
 		}
 	}

From 531de2a9bf55772d5ecf0aea678d4f4944716c82 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 21 Dec 2019 07:22:04 +0100
Subject: [PATCH 114/120] Day 21

---
 .../sbaars/adventofcode2019/days/Day17.java   |  3 +-
 .../sbaars/adventofcode2019/days/Day21.java   | 47 +++++++++++++++++++
 .../intcode/IntcodeComputer.java              |  4 ++
 src/main/resources/day21.txt                  |  1 +
 4 files changed, 53 insertions(+), 2 deletions(-)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day21.java
 create mode 100644 src/main/resources/day21.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
index 9b180a8b..85431b73 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day17.java
@@ -68,9 +68,8 @@ public Object part2() throws IOException {
 			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);
+		ic.setInput(patterns);
 		while(true) {
 			long res = ic.run();
 			if(res>255L)
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day21.java b/src/main/java/com/sbaars/adventofcode2019/days/Day21.java
new file mode 100644
index 00000000..c37e7a53
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day21.java
@@ -0,0 +1,47 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+
+import com.sbaars.adventofcode2019.common.Day;
+import com.sbaars.adventofcode2019.intcode.IntcodeComputer;
+
+public class Day21 implements Day {
+
+	public static void main(String[] args) throws IOException {
+		new Day21().printParts();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		IntcodeComputer ic = new IntcodeComputer(21);
+		ic.setInput("OR A T\n" + 
+				"AND B T\n" + 
+				"AND C T\n" + 
+				"NOT T T\n" +  //flip T
+				"AND D T\n" + 
+				"OR T J\n" + 
+				"WALK\n");
+		long res;
+		while((res = ic.run()) != IntcodeComputer.STOP_CODE)
+			if(res>255) return res;
+		return 0;
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		IntcodeComputer ic = new IntcodeComputer(21);
+		ic.setInput("NOT A J\n" + 
+				"NOT B T\n" + 
+				"AND H T\n" + 
+				"OR T J\n" + 
+				"NOT C T\n" + 
+				"AND H T\n" + 
+				"OR T J\n" + 
+				"AND D J\n" + 
+				"RUN\n");
+		long res;
+		while((res = ic.run()) != IntcodeComputer.STOP_CODE)
+			if(res>255) return res;
+		return 0;
+	}
+}
diff --git a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
index 1100ec10..38136371 100644
--- a/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
+++ b/src/main/java/com/sbaars/adventofcode2019/intcode/IntcodeComputer.java
@@ -148,4 +148,8 @@ private int nParams(int instruction) {
 	public void setElement(int i, long j) {
 		program[i] = j;
 	}
+
+	public void setInput(String patterns) {
+		setInput(patterns.chars().mapToLong(e -> e).toArray());
+	}
 }
diff --git a/src/main/resources/day21.txt b/src/main/resources/day21.txt
new file mode 100644
index 00000000..445de007
--- /dev/null
+++ b/src/main/resources/day21.txt
@@ -0,0 +1 @@
+109,2050,21101,966,0,1,21102,1,13,0,1105,1,1378,21102,20,1,0,1106,0,1337,21101,0,27,0,1106,0,1279,1208,1,65,748,1005,748,73,1208,1,79,748,1005,748,110,1208,1,78,748,1005,748,132,1208,1,87,748,1005,748,169,1208,1,82,748,1005,748,239,21102,1041,1,1,21102,73,1,0,1105,1,1421,21101,78,0,1,21101,1041,0,2,21102,88,1,0,1106,0,1301,21102,1,68,1,21101,1041,0,2,21102,1,103,0,1105,1,1301,1101,0,1,750,1106,0,298,21102,82,1,1,21101,1041,0,2,21101,125,0,0,1106,0,1301,1101,2,0,750,1106,0,298,21102,79,1,1,21101,0,1041,2,21101,147,0,0,1105,1,1301,21101,84,0,1,21102,1041,1,2,21102,162,1,0,1106,0,1301,1101,3,0,750,1106,0,298,21102,65,1,1,21102,1,1041,2,21102,184,1,0,1105,1,1301,21102,1,76,1,21102,1,1041,2,21101,0,199,0,1106,0,1301,21102,75,1,1,21101,1041,0,2,21102,1,214,0,1106,0,1301,21101,0,221,0,1106,0,1337,21101,0,10,1,21102,1,1041,2,21102,236,1,0,1105,1,1301,1106,0,553,21102,1,85,1,21101,1041,0,2,21101,0,254,0,1105,1,1301,21102,78,1,1,21101,0,1041,2,21102,1,269,0,1105,1,1301,21101,276,0,0,1106,0,1337,21101,0,10,1,21101,0,1041,2,21102,1,291,0,1105,1,1301,1101,0,1,755,1105,1,553,21101,0,32,1,21101,1041,0,2,21101,0,313,0,1105,1,1301,21102,1,320,0,1106,0,1337,21102,1,327,0,1106,0,1279,2102,1,1,749,21101,0,65,2,21102,1,73,3,21101,0,346,0,1105,1,1889,1206,1,367,1007,749,69,748,1005,748,360,1101,0,1,756,1001,749,-64,751,1106,0,406,1008,749,74,748,1006,748,381,1102,-1,1,751,1106,0,406,1008,749,84,748,1006,748,395,1101,-2,0,751,1105,1,406,21101,1100,0,1,21102,406,1,0,1105,1,1421,21101,0,32,1,21102,1100,1,2,21102,1,421,0,1105,1,1301,21102,1,428,0,1105,1,1337,21102,1,435,0,1105,1,1279,2101,0,1,749,1008,749,74,748,1006,748,453,1101,0,-1,752,1106,0,478,1008,749,84,748,1006,748,467,1101,-2,0,752,1106,0,478,21102,1168,1,1,21101,0,478,0,1105,1,1421,21101,485,0,0,1105,1,1337,21102,10,1,1,21101,1168,0,2,21101,0,500,0,1105,1,1301,1007,920,15,748,1005,748,518,21101,0,1209,1,21102,518,1,0,1106,0,1421,1002,920,3,529,1001,529,921,529,1002,750,1,0,1001,529,1,537,1001,751,0,0,1001,537,1,545,101,0,752,0,1001,920,1,920,1106,0,13,1005,755,577,1006,756,570,21101,1100,0,1,21102,1,570,0,1105,1,1421,21102,1,987,1,1106,0,581,21101,1001,0,1,21101,588,0,0,1105,1,1378,1102,1,758,594,101,0,0,753,1006,753,654,21001,753,0,1,21102,610,1,0,1106,0,667,21101,0,0,1,21101,621,0,0,1105,1,1463,1205,1,647,21102,1015,1,1,21101,635,0,0,1105,1,1378,21102,1,1,1,21102,1,646,0,1105,1,1463,99,1001,594,1,594,1106,0,592,1006,755,664,1101,0,0,755,1106,0,647,4,754,99,109,2,1101,726,0,757,21201,-1,0,1,21101,9,0,2,21101,697,0,3,21102,1,692,0,1106,0,1913,109,-2,2106,0,0,109,2,101,0,757,706,1201,-1,0,0,1001,757,1,757,109,-2,2106,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,255,63,223,127,159,191,95,0,183,170,218,117,217,86,155,244,187,178,56,109,253,154,38,184,213,110,189,233,212,87,50,141,169,125,236,207,171,175,230,114,137,197,99,49,249,136,239,93,242,57,231,100,228,172,219,102,140,69,84,206,92,174,77,179,166,76,163,139,203,120,173,43,62,202,124,216,103,138,71,39,54,143,227,79,157,158,167,250,126,198,235,58,121,251,156,199,35,68,246,215,53,47,185,221,182,46,168,115,51,123,142,229,85,111,201,248,107,204,70,98,34,42,188,222,60,254,196,162,220,153,78,61,55,119,252,186,181,243,238,101,118,106,214,234,226,113,108,94,152,116,200,232,59,190,247,122,245,205,237,241,177,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,73,110,112,117,116,32,105,110,115,116,114,117,99,116,105,111,110,115,58,10,13,10,87,97,108,107,105,110,103,46,46,46,10,10,13,10,82,117,110,110,105,110,103,46,46,46,10,10,25,10,68,105,100,110,39,116,32,109,97,107,101,32,105,116,32,97,99,114,111,115,115,58,10,10,58,73,110,118,97,108,105,100,32,111,112,101,114,97,116,105,111,110,59,32,101,120,112,101,99,116,101,100,32,115,111,109,101,116,104,105,110,103,32,108,105,107,101,32,65,78,68,44,32,79,82,44,32,111,114,32,78,79,84,67,73,110,118,97,108,105,100,32,102,105,114,115,116,32,97,114,103,117,109,101,110,116,59,32,101,120,112,101,99,116,101,100,32,115,111,109,101,116,104,105,110,103,32,108,105,107,101,32,65,44,32,66,44,32,67,44,32,68,44,32,74,44,32,111,114,32,84,40,73,110,118,97,108,105,100,32,115,101,99,111,110,100,32,97,114,103,117,109,101,110,116,59,32,101,120,112,101,99,116,101,100,32,74,32,111,114,32,84,52,79,117,116,32,111,102,32,109,101,109,111,114,121,59,32,97,116,32,109,111,115,116,32,49,53,32,105,110,115,116,114,117,99,116,105,111,110,115,32,99,97,110,32,98,101,32,115,116,111,114,101,100,0,109,1,1005,1262,1270,3,1262,21002,1262,1,0,109,-1,2105,1,0,109,1,21102,1,1288,0,1105,1,1263,21001,1262,0,0,1102,1,0,1262,109,-1,2105,1,0,109,5,21101,0,1310,0,1106,0,1279,22101,0,1,-2,22208,-2,-4,-1,1205,-1,1332,22102,1,-3,1,21102,1332,1,0,1105,1,1421,109,-5,2105,1,0,109,2,21101,1346,0,0,1105,1,1263,21208,1,32,-1,1205,-1,1363,21208,1,9,-1,1205,-1,1363,1106,0,1373,21101,0,1370,0,1105,1,1279,1106,0,1339,109,-2,2105,1,0,109,5,2102,1,-4,1385,21001,0,0,-2,22101,1,-4,-4,21101,0,0,-3,22208,-3,-2,-1,1205,-1,1416,2201,-4,-3,1408,4,0,21201,-3,1,-3,1106,0,1396,109,-5,2105,1,0,109,2,104,10,22102,1,-1,1,21102,1436,1,0,1106,0,1378,104,10,99,109,-2,2105,1,0,109,3,20002,594,753,-1,22202,-1,-2,-1,201,-1,754,754,109,-3,2106,0,0,109,10,21101,0,5,-5,21102,1,1,-4,21102,0,1,-3,1206,-9,1555,21101,3,0,-6,21102,1,5,-7,22208,-7,-5,-8,1206,-8,1507,22208,-6,-4,-8,1206,-8,1507,104,64,1106,0,1529,1205,-6,1527,1201,-7,716,1515,21002,0,-11,-8,21201,-8,46,-8,204,-8,1106,0,1529,104,46,21201,-7,1,-7,21207,-7,22,-8,1205,-8,1488,104,10,21201,-6,-1,-6,21207,-6,0,-8,1206,-8,1484,104,10,21207,-4,1,-8,1206,-8,1569,21101,0,0,-9,1105,1,1689,21208,-5,21,-8,1206,-8,1583,21102,1,1,-9,1105,1,1689,1201,-5,716,1589,20102,1,0,-2,21208,-4,1,-1,22202,-2,-1,-1,1205,-2,1613,21201,-5,0,1,21101,0,1613,0,1106,0,1444,1206,-1,1634,22101,0,-5,1,21101,1627,0,0,1105,1,1694,1206,1,1634,21101,0,2,-3,22107,1,-4,-8,22201,-1,-8,-8,1206,-8,1649,21201,-5,1,-5,1206,-3,1663,21201,-3,-1,-3,21201,-4,1,-4,1106,0,1667,21201,-4,-1,-4,21208,-4,0,-1,1201,-5,716,1676,22002,0,-1,-1,1206,-1,1686,21101,1,0,-4,1106,0,1477,109,-10,2106,0,0,109,11,21101,0,0,-6,21102,0,1,-8,21101,0,0,-7,20208,-6,920,-9,1205,-9,1880,21202,-6,3,-9,1201,-9,921,1725,20101,0,0,-5,1001,1725,1,1732,21002,0,1,-4,21202,-4,1,1,21102,1,1,2,21101,9,0,3,21102,1,1754,0,1105,1,1889,1206,1,1772,2201,-10,-4,1766,1001,1766,716,1766,21001,0,0,-3,1105,1,1790,21208,-4,-1,-9,1206,-9,1786,22102,1,-8,-3,1105,1,1790,21202,-7,1,-3,1001,1732,1,1795,21002,0,1,-2,21208,-2,-1,-9,1206,-9,1812,21201,-8,0,-1,1106,0,1816,21202,-7,1,-1,21208,-5,1,-9,1205,-9,1837,21208,-5,2,-9,1205,-9,1844,21208,-3,0,-1,1106,0,1855,22202,-3,-1,-1,1106,0,1855,22201,-3,-1,-1,22107,0,-1,-1,1106,0,1855,21208,-2,-1,-9,1206,-9,1869,22101,0,-1,-8,1106,0,1873,21201,-1,0,-7,21201,-6,1,-6,1106,0,1708,22101,0,-8,-10,109,-11,2106,0,0,109,7,22207,-6,-5,-3,22207,-4,-6,-2,22201,-3,-2,-1,21208,-1,0,-6,109,-7,2106,0,0,0,109,5,2101,0,-2,1912,21207,-4,0,-1,1206,-1,1930,21101,0,0,-4,21201,-4,0,1,21202,-3,1,2,21101,0,1,3,21102,1,1949,0,1106,0,1954,109,-5,2105,1,0,109,6,21207,-4,1,-1,1206,-1,1977,22207,-5,-3,-1,1206,-1,1977,22101,0,-5,-5,1105,1,2045,21201,-5,0,1,21201,-4,-1,2,21202,-3,2,3,21101,1996,0,0,1106,0,1954,22101,0,1,-5,21102,1,1,-2,22207,-5,-3,-1,1206,-1,2015,21102,1,0,-2,22202,-3,-2,-3,22107,0,-4,-1,1206,-1,2037,21201,-2,0,1,21102,2037,1,0,106,0,1912,21202,-3,-1,-3,22201,-5,-3,-5,109,-6,2105,1,0
\ No newline at end of file

From e255fa09953cd2b0ddfd24f276f6d0bf29388b22 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 21 Dec 2019 08:24:56 +0100
Subject: [PATCH 115/120] Added comments denoting the boolean logic

---
 .../java/com/sbaars/adventofcode2019/days/Day20.java   | 10 +++++-----
 .../java/com/sbaars/adventofcode2019/days/Day21.java   |  2 ++
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index 363874a5..03680045 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -119,14 +119,14 @@ private int findRoutes(boolean b) {
 		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(s.level < 0) continue;
 			if(!routes.containsKey(s.pos)) determineRoutes(s.pos);
 			for(Route route : routes.get(s.pos)) {
 				int level = s.level;
+				if(level == 0 && route.goal.equals(exit)) {
+					System.out.println(s.debug);
+					return route.distance + s.totalSteps - 1;
+				} else if(route.goal.equals(exit)) continue;
 				if(b) level+=route.goal.isOuter ? -1 : 1;
 				Visited vis = new Visited(route.goal, level);
 				if(!visited.contains(vis)) {
diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day21.java b/src/main/java/com/sbaars/adventofcode2019/days/Day21.java
index c37e7a53..9b1a3a73 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day21.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day21.java
@@ -14,6 +14,7 @@ public static void main(String[] args) throws IOException {
 	@Override
 	public Object part1() throws IOException {
 		IntcodeComputer ic = new IntcodeComputer(21);
+		// !(A && B && C) || D
 		ic.setInput("OR A T\n" + 
 				"AND B T\n" + 
 				"AND C T\n" + 
@@ -30,6 +31,7 @@ public Object part1() throws IOException {
 	@Override
 	public Object part2() throws IOException {
 		IntcodeComputer ic = new IntcodeComputer(21);
+		// (((!B && H) || !A) || (!C && H)) && D
 		ic.setInput("NOT A J\n" + 
 				"NOT B T\n" + 
 				"AND H T\n" + 

From d4c6b4272cdeea0a5f6a1d8472e17dd773eb0e63 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 21 Dec 2019 09:07:24 +0100
Subject: [PATCH 116/120] Day 20 debug

---
 .../java/com/sbaars/adventofcode2019/days/Day20.java   | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index 03680045..607b178c 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -116,22 +116,22 @@ public Object part1() throws IOException {
 	private int findRoutes(boolean b) {
 		final Queue<State> queue = new ArrayDeque<>();
 		final Set<Visited> visited = new HashSet<>();
-		queue.add(new State("", 0, new Visited(entry, 0)));
+		queue.add(new State("", -1, new Visited(entry, 0)));
 		while(true) {
 			State s = queue.poll();
-			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(level == 0 && route.goal.equals(exit)) {
 					System.out.println(s.debug);
-					return route.distance + s.totalSteps - 1;
+					return route.distance + s.totalSteps;
 				} else if(route.goal.equals(exit)) continue;
-				if(b) level+=route.goal.isOuter ? -1 : 1;
+				if(b) level+=route.goal.isOuter ? 1 : -1;
+				if(s.level < 0) continue;
 				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));
+					queue.add(new State(s.debug+" "+(route.goal.isOuter ? '-' : '+')+portalLabel.get(route.goal)+":"+(s.totalSteps + route.distance) + "(" + s.level + ")", s.totalSteps + route.distance, vis));
 				}
 			}
 		}

From f3f1d66025680d9160b21b195fe2d3ae91a80f6d Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sat, 21 Dec 2019 09:08:40 +0100
Subject: [PATCH 117/120] Day 20: removed debug

---
 .../com/sbaars/adventofcode2019/days/Day20.java    | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
index 607b178c..253b327b 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day20.java
@@ -44,12 +44,10 @@ public class Day20 implements Day {
 	
 	@EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @AllArgsConstructor class State extends Visited {
 		int totalSteps;
-		String debug = "";
 		
-		public State(String debug, int totalSteps, Visited vis) {
+		public State(int totalSteps, Visited vis) {
 			super(vis.pos, vis.level);
 			this.totalSteps = totalSteps;
-			this.debug = debug;
 		}
 	}
 	
@@ -116,22 +114,20 @@ public Object part1() throws IOException {
 	private int findRoutes(boolean b) {
 		final Queue<State> queue = new ArrayDeque<>();
 		final Set<Visited> visited = new HashSet<>();
-		queue.add(new State("", -1, new Visited(entry, 0)));
+		queue.add(new State(-1, new Visited(entry, 0)));
 		while(true) {
 			State s = queue.poll();
 			if(!routes.containsKey(s.pos)) determineRoutes(s.pos);
 			for(Route route : routes.get(s.pos)) {
 				int level = s.level;
-				if(level == 0 && route.goal.equals(exit)) {
-					System.out.println(s.debug);
-					return route.distance + s.totalSteps;
-				} else if(route.goal.equals(exit)) continue;
+				if(level == 0 && route.goal.equals(exit)) return route.distance + s.totalSteps;
+				else if(route.goal.equals(exit)) continue;
 				if(b) level+=route.goal.isOuter ? 1 : -1;
 				if(s.level < 0) continue;
 				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.level + ")", s.totalSteps + route.distance, vis));
+					queue.add(new State(s.totalSteps + route.distance, vis));
 				}
 			}
 		}

From 7ff79d55eb9650c69b8bb39d361d5ee92e71bee3 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 22 Dec 2019 14:17:41 +0100
Subject: [PATCH 118/120] Day 22

---
 .../sbaars/adventofcode2019/days/Day22.java   | 125 ++++++++++++++++++
 src/main/resources/day22.txt                  | 100 ++++++++++++++
 2 files changed, 225 insertions(+)
 create mode 100644 src/main/java/com/sbaars/adventofcode2019/days/Day22.java
 create mode 100644 src/main/resources/day22.txt

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day22.java b/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
new file mode 100644
index 00000000..32839a7b
--- /dev/null
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
@@ -0,0 +1,125 @@
+package com.sbaars.adventofcode2019.days;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import com.sbaars.adventofcode2019.common.Day;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Value;
+
+public class Day22 implements Day {
+	
+	Move[] moves;
+
+	public Day22() throws IOException {
+		this.moves = Arrays.stream(readDay(22).split(System.lineSeparator())).map(Move::new).toArray(Move[]::new);
+	}
+	
+	public static void main(String[] args) throws IOException {
+		new Day22().printParts();
+	}
+	
+	@AllArgsConstructor enum Action{
+		DEAL_WITH_INCREMENT("deal with increment "),
+		DEAL_NEW_STACK("deal into new stack"),
+		CUT("cut ");
+		
+		String name;
+		
+		public static Action actionByText(String text) {
+			return Arrays.stream(values()).filter(a -> text.startsWith(a.name)).findAny().get();
+		}
+	}
+	
+	@Value @Data class Move {
+		Action action;
+		int amount;
+		
+		public Move(String s) {
+			this.action = Action.actionByText(s);
+			s = s.replace(action.name, "");
+			if(!s.isEmpty()) amount = Integer.parseInt(s);
+			else amount = 0;
+		}
+
+		public List<Integer> execute(List<Integer> cards) {
+			switch(action) {
+				case DEAL_NEW_STACK: Collections.reverse(cards); break;
+				case CUT: {
+					int n = amount > 0 ? amount : cards.size()+amount;
+					List<Integer> sub = new ArrayList<>(cards.subList(n, cards.size()));
+					sub.addAll(cards.subList(0, n));
+					return sub;
+				} 
+				case DEAL_WITH_INCREMENT: {
+					Integer[] deck = new Integer[cards.size()] ;
+					for(int i = 0, card = 0; i<cards.size();i++) {
+						deck[card] = cards.get(i);
+						card = (card + amount) % deck.length;
+					}
+					return Arrays.asList(deck);
+				}
+			}
+			return cards;
+		}
+		
+		public long[] execute(long[] input, long deckSize) {
+			switch(action) {
+				case DEAL_NEW_STACK: return new long[] {-input[0], -(input[1]+1)};
+				case CUT: input[1] += amount; break;
+				case DEAL_WITH_INCREMENT: {
+					long p = pow(amount, deckSize-2, deckSize);
+					return new long[] {input[0]*p, input[1]*p};
+				}
+			}
+			return input;
+		}
+	}
+	
+	private long pow(long a, long b, long c) {
+		return new BigInteger(Long.toString(a)).modPow(new BigInteger(Long.toString(b)), new BigInteger(Long.toString(c))).longValue();
+	}
+
+	@Override
+	public Object part1() throws IOException {
+		List<Integer> cards = IntStream.range(0, 10007).boxed().collect(Collectors.toList());
+		for(Move move : moves) cards = move.execute(cards);
+		return cards.indexOf(2019);
+	}
+	
+	@Override
+	public Object part2() throws IOException {
+		long deckSize = 119315717514047L;
+		long timesShuffled = 101741582076661L;
+		long[] calc = new long[] {1, 0};
+		System.out.println("Max long "+Long.MAX_VALUE);
+		for(Move move : reverseArray(moves)) {
+			System.out.println(move);
+			calc = move.execute(calc, deckSize);
+			//System.out.println("Before mod: "+Arrays.toString(calc));
+			for(int i = 0; i<calc.length; i++) calc[i] = Math.floorMod(calc[i], deckSize);
+			//calc[0] %= deckSize;
+			//calc[1] %= deckSize;
+			System.out.println("after mod: "+Arrays.toString(calc));
+		}
+		long pow = pow(calc[0], timesShuffled, deckSize);
+		return Math.floorMod(pow * 2020 + calc[1] * (pow + deckSize - 1) * pow(calc[0] - 1, deckSize - 2, deckSize), deckSize);
+	}
+	
+	private <T> T[] reverseArray(T[] arr) {
+		for(int i = 0; i < arr.length / 2; i++) {
+		    T temp = arr[i];
+		    arr[i] = arr[arr.length - i - 1];
+		    arr[arr.length - i - 1] = temp;
+		}
+		return arr;
+	}
+}
diff --git a/src/main/resources/day22.txt b/src/main/resources/day22.txt
new file mode 100644
index 00000000..55ab7933
--- /dev/null
+++ b/src/main/resources/day22.txt
@@ -0,0 +1,100 @@
+deal with increment 31
+deal into new stack
+cut -7558
+deal with increment 49
+cut 194
+deal with increment 23
+cut -4891
+deal with increment 53
+cut 5938
+deal with increment 61
+cut 7454
+deal into new stack
+deal with increment 31
+cut 3138
+deal with increment 53
+cut 3553
+deal with increment 61
+cut -5824
+deal with increment 42
+cut -889
+deal with increment 34
+cut 7128
+deal with increment 42
+cut -9003
+deal with increment 75
+cut 13
+deal with increment 75
+cut -3065
+deal with increment 74
+cut -8156
+deal with increment 39
+cut 4242
+deal with increment 24
+cut -405
+deal with increment 27
+cut 6273
+deal with increment 19
+cut -9826
+deal with increment 58
+deal into new stack
+cut -6927
+deal with increment 65
+cut -9906
+deal with increment 31
+deal into new stack
+deal with increment 42
+deal into new stack
+deal with increment 39
+cut -4271
+deal into new stack
+deal with increment 32
+cut -8799
+deal with increment 69
+cut 2277
+deal with increment 55
+cut 2871
+deal with increment 54
+cut -2118
+deal with increment 15
+cut 1529
+deal with increment 57
+cut -4745
+deal with increment 23
+cut -5959
+deal with increment 58
+deal into new stack
+deal with increment 48
+deal into new stack
+cut 2501
+deal into new stack
+deal with increment 42
+deal into new stack
+cut 831
+deal with increment 74
+cut -3119
+deal with increment 33
+cut 967
+deal with increment 69
+cut 9191
+deal with increment 9
+cut 5489
+deal with increment 62
+cut -9107
+deal with increment 14
+cut -7717
+deal with increment 56
+cut 7900
+deal with increment 49
+cut 631
+deal with increment 14
+deal into new stack
+deal with increment 58
+cut -9978
+deal with increment 48
+deal into new stack
+deal with increment 66
+cut -1554
+deal into new stack
+cut 897
+deal with increment 36
\ No newline at end of file

From d2a230aef9fea32ae9368ffe773a62a3787d416d Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 22 Dec 2019 14:49:17 +0100
Subject: [PATCH 119/120] Use big integers

---
 .../sbaars/adventofcode2019/days/Day22.java   | 35 ++++++++++---------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day22.java b/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
index 32839a7b..dd074632 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
@@ -71,23 +71,26 @@ public List<Integer> execute(List<Integer> cards) {
 			return cards;
 		}
 		
-		public long[] execute(long[] input, long deckSize) {
+		public BigInteger[] execute(BigInteger[] input, BigInteger deckSize) {
 			switch(action) {
-				case DEAL_NEW_STACK: return new long[] {-input[0], -(input[1]+1)};
-				case CUT: input[1] += amount; break;
+				case DEAL_NEW_STACK: {
+					input[0] = input[0].multiply(num(-1));
+					input[1] = input[1].add(num(1)).multiply(num(-1));
+				} break;
+				case CUT: input[1] = input[1].add(num(amount)); break;
 				case DEAL_WITH_INCREMENT: {
-					long p = pow(amount, deckSize-2, deckSize);
-					return new long[] {input[0]*p, input[1]*p};
-				}
+					BigInteger p = num(amount).modPow(deckSize.min(num(2)), deckSize);
+					for(int i = 0; i<input.length; i++) input[i] = input[i].multiply(p);
+				} break;
 			}
 			return input;
 		}
 	}
 	
-	private long pow(long a, long b, long c) {
-		return new BigInteger(Long.toString(a)).modPow(new BigInteger(Long.toString(b)), new BigInteger(Long.toString(c))).longValue();
+	private BigInteger num(long n) {
+		return new BigInteger(Long.toString(n));
 	}
-
+	
 	@Override
 	public Object part1() throws IOException {
 		List<Integer> cards = IntStream.range(0, 10007).boxed().collect(Collectors.toList());
@@ -97,21 +100,21 @@ public Object part1() throws IOException {
 	
 	@Override
 	public Object part2() throws IOException {
-		long deckSize = 119315717514047L;
-		long timesShuffled = 101741582076661L;
-		long[] calc = new long[] {1, 0};
-		System.out.println("Max long "+Long.MAX_VALUE);
+		BigInteger deckSize = num(119315717514047L);
+		BigInteger timesShuffled = num(101741582076661L);
+		BigInteger[] calc = new BigInteger[] {num(1), num(0)};
 		for(Move move : reverseArray(moves)) {
 			System.out.println(move);
 			calc = move.execute(calc, deckSize);
 			//System.out.println("Before mod: "+Arrays.toString(calc));
-			for(int i = 0; i<calc.length; i++) calc[i] = Math.floorMod(calc[i], deckSize);
+			for(int i = 0; i<calc.length; i++) calc[i] = calc[i].mod(deckSize);
 			//calc[0] %= deckSize;
 			//calc[1] %= deckSize;
 			System.out.println("after mod: "+Arrays.toString(calc));
 		}
-		long pow = pow(calc[0], timesShuffled, deckSize);
-		return Math.floorMod(pow * 2020 + calc[1] * (pow + deckSize - 1) * pow(calc[0] - 1, deckSize - 2, deckSize), deckSize);
+		BigInteger pow = calc[0].modPow(timesShuffled, deckSize);
+		//return Math.floorMod(pow.multiply(num(2020)).add(calc[1]).multiply((pow + deckSize - 1) * pow(calc[0] - 1, deckSize - 2, deckSize), deckSize);
+		return pow.multiply(num(2020)).add(calc[1].multiply(pow.add(deckSize).min(num(1))).multiply(calc[0].min(num(1)).modPow(deckSize.min(num(2)), deckSize))).mod(deckSize);
 	}
 	
 	private <T> T[] reverseArray(T[] arr) {

From fec4a7e5247e163e0fa6edbf05938f335fe2e047 Mon Sep 17 00:00:00 2001
From: Simon <simon.mailadres@gmail.com>
Date: Sun, 22 Dec 2019 14:56:56 +0100
Subject: [PATCH 120/120] Finish up day 22

---
 .../sbaars/adventofcode2019/days/Day22.java   | 20 +++++++------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/sbaars/adventofcode2019/days/Day22.java b/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
index dd074632..4c6ad1e2 100644
--- a/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
+++ b/src/main/java/com/sbaars/adventofcode2019/days/Day22.java
@@ -27,7 +27,7 @@ public static void main(String[] args) throws IOException {
 		new Day22().printParts();
 	}
 	
-	@AllArgsConstructor enum Action{
+	@AllArgsConstructor enum Action {
 		DEAL_WITH_INCREMENT("deal with increment "),
 		DEAL_NEW_STACK("deal into new stack"),
 		CUT("cut ");
@@ -79,7 +79,7 @@ public BigInteger[] execute(BigInteger[] input, BigInteger deckSize) {
 				} break;
 				case CUT: input[1] = input[1].add(num(amount)); break;
 				case DEAL_WITH_INCREMENT: {
-					BigInteger p = num(amount).modPow(deckSize.min(num(2)), deckSize);
+					var p = num(amount).modPow(deckSize.subtract(num(2)), deckSize);
 					for(int i = 0; i<input.length; i++) input[i] = input[i].multiply(p);
 				} break;
 			}
@@ -100,21 +100,15 @@ public Object part1() throws IOException {
 	
 	@Override
 	public Object part2() throws IOException {
-		BigInteger deckSize = num(119315717514047L);
-		BigInteger timesShuffled = num(101741582076661L);
-		BigInteger[] calc = new BigInteger[] {num(1), num(0)};
+		var deckSize = num(119315717514047L);
+		var timesShuffled = num(101741582076661L);
+		var calc = new BigInteger[] {num(1), num(0)};
 		for(Move move : reverseArray(moves)) {
-			System.out.println(move);
 			calc = move.execute(calc, deckSize);
-			//System.out.println("Before mod: "+Arrays.toString(calc));
 			for(int i = 0; i<calc.length; i++) calc[i] = calc[i].mod(deckSize);
-			//calc[0] %= deckSize;
-			//calc[1] %= deckSize;
-			System.out.println("after mod: "+Arrays.toString(calc));
 		}
-		BigInteger pow = calc[0].modPow(timesShuffled, deckSize);
-		//return Math.floorMod(pow.multiply(num(2020)).add(calc[1]).multiply((pow + deckSize - 1) * pow(calc[0] - 1, deckSize - 2, deckSize), deckSize);
-		return pow.multiply(num(2020)).add(calc[1].multiply(pow.add(deckSize).min(num(1))).multiply(calc[0].min(num(1)).modPow(deckSize.min(num(2)), deckSize))).mod(deckSize);
+		var pow = calc[0].modPow(timesShuffled, deckSize);
+		return pow.multiply(num(2020)).add(calc[1].multiply(pow.add(deckSize).subtract(num(1))).multiply(calc[0].subtract(num(1)).modPow(deckSize.subtract(num(2)), deckSize))).mod(deckSize);
 	}
 	
 	private <T> T[] reverseArray(T[] arr) {