Day 3-6 2019
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package be.vandewalleh.aoc;
|
||||
|
||||
import be.vandewalleh.aoc.geometry.Direction2D;
|
||||
import be.vandewalleh.aoc.geometry.Point2D;
|
||||
import be.vandewalleh.aoc.utils.factory.Days;
|
||||
import be.vandewalleh.aoc.utils.input.Day;
|
||||
import be.vandewalleh.aoc.utils.input.Input;
|
||||
import be.vandewalleh.aoc.utils.input.Lines;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
@Day(3)
|
||||
public class Day03 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
var day = Days.createDay(Day03.class);
|
||||
System.out.println(day.part1());
|
||||
System.out.println(day.part2());
|
||||
}
|
||||
|
||||
private final String[] wireA;
|
||||
private final String[] wireB;
|
||||
|
||||
public Day03(@Lines Input<List<String>> input) {
|
||||
this.wireA = input.getValue().get(0).split(",");
|
||||
this.wireB = input.getValue().get(1).split(",");
|
||||
}
|
||||
|
||||
private List<Point2D> path(String[] wire) {
|
||||
var points = new ArrayList<Point2D>();
|
||||
var point = Point2D.origin;
|
||||
for (var section : wire) {
|
||||
var direction = Direction2D.from(section.charAt(0));
|
||||
var count = Integer.parseInt(section.substring(1));
|
||||
for (int i = 0; i < count; i++) {
|
||||
point = point.translate(direction.point);
|
||||
points.add(point);
|
||||
}
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
private int part1() {
|
||||
var pathA = path(wireA);
|
||||
var pathB = path(wireB);
|
||||
|
||||
var intersections = new HashSet<>(pathA);
|
||||
intersections.retainAll(pathB);
|
||||
|
||||
return intersections.stream().mapToInt(Point2D::manhattanDistance).min().orElse(-1);
|
||||
}
|
||||
|
||||
private int part2() {
|
||||
var pathA = path(wireA);
|
||||
var pathB = path(wireB);
|
||||
|
||||
var intersections = new HashSet<>(pathA);
|
||||
intersections.retainAll(pathB);
|
||||
|
||||
return intersections.stream().mapToInt(p -> pathA.indexOf(p) + pathB.indexOf(p) + 2).min().orElse(-1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package be.vandewalleh.aoc;
|
||||
|
||||
import be.vandewalleh.aoc.utils.factory.Days;
|
||||
import be.vandewalleh.aoc.utils.input.Day;
|
||||
import be.vandewalleh.aoc.utils.input.Input;
|
||||
import be.vandewalleh.aoc.utils.input.Text;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Day(4)
|
||||
public class Day04 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
var day = Days.createDay(Day04.class);
|
||||
System.out.println(day.part1());
|
||||
System.out.println(day.part2());
|
||||
}
|
||||
|
||||
private final int min;
|
||||
private final int max;
|
||||
|
||||
public Day04(@Text Input<String> input) {
|
||||
var spl = input.getValue().split("-", 2);
|
||||
min = Integer.parseInt(spl[0]);
|
||||
max = Integer.parseInt(spl[1]);
|
||||
}
|
||||
|
||||
private boolean isNotDecreasing(int[] ints) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int a = ints[i], b = ints[i + 1];
|
||||
if (b < a) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasPair(int[] ints) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int a = ints[i], b = ints[i + 1];
|
||||
if (a == b) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasGroup(int[] ints) {
|
||||
var occurrences = new int[10];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int a = ints[i], b = ints[i + 1];
|
||||
if (a == b) occurrences[a]++;
|
||||
}
|
||||
return Arrays.stream(occurrences).anyMatch(e -> e == 1);
|
||||
}
|
||||
|
||||
private Stream<int[]> intStream() {
|
||||
return IntStream.rangeClosed(min, max)
|
||||
.mapToObj(String::valueOf)
|
||||
.map(String::toCharArray)
|
||||
.map(e -> {
|
||||
var ints = new int[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
ints[i] = Integer.parseInt(String.valueOf(e[i]));
|
||||
}
|
||||
return ints;
|
||||
});
|
||||
}
|
||||
|
||||
private long part1() {
|
||||
return intStream()
|
||||
.filter(this::isNotDecreasing)
|
||||
.filter(this::hasPair)
|
||||
.count();
|
||||
}
|
||||
|
||||
private long part2() {
|
||||
return intStream()
|
||||
.filter(this::isNotDecreasing)
|
||||
.filter(this::hasGroup)
|
||||
.count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package be.vandewalleh.aoc;
|
||||
|
||||
import be.vandewalleh.aoc.intcode.IntCodeInterpreter;
|
||||
import be.vandewalleh.aoc.utils.factory.Days;
|
||||
import be.vandewalleh.aoc.utils.input.Csv;
|
||||
import be.vandewalleh.aoc.utils.input.Day;
|
||||
import be.vandewalleh.aoc.utils.input.Input;
|
||||
|
||||
@Day(5)
|
||||
public class Day05 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
var day = Days.createDay(Day05.class);
|
||||
System.out.println(day.part1());
|
||||
System.out.println(day.part2());
|
||||
}
|
||||
|
||||
private final int[] input;
|
||||
|
||||
public Day05(@Csv Input<int[]> input) {
|
||||
this.input = input.getValue();
|
||||
}
|
||||
|
||||
private Long part1() {
|
||||
var interpreter = new IntCodeInterpreter(input);
|
||||
interpreter.setInput(1);
|
||||
interpreter.run();
|
||||
return interpreter.getOutputs().peek();
|
||||
}
|
||||
|
||||
private Long part2() {
|
||||
var interpreter = new IntCodeInterpreter(input);
|
||||
interpreter.setInput(5);
|
||||
interpreter.run();
|
||||
return interpreter.getOutputs().peek();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package be.vandewalleh.aoc;
|
||||
|
||||
import be.vandewalleh.aoc.utils.factory.Days;
|
||||
import be.vandewalleh.aoc.utils.input.Day;
|
||||
import be.vandewalleh.aoc.utils.input.Input;
|
||||
import be.vandewalleh.aoc.utils.input.Lines;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Day(6)
|
||||
public class Day06 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
var day = Days.createDay(Day06.class);
|
||||
System.out.println(day.part1());
|
||||
System.out.println(day.part2());
|
||||
}
|
||||
|
||||
private final List<String> input;
|
||||
|
||||
public Day06(@Lines Input<List<String>> input) {
|
||||
this.input = input.getValue();
|
||||
}
|
||||
|
||||
private final Map<String, String> reverseOrbits = new HashMap<>();
|
||||
|
||||
private int countDirectOrbits() {
|
||||
return reverseOrbits.size();
|
||||
}
|
||||
|
||||
private int countIndirectOrbits() {
|
||||
var count = 0;
|
||||
for (var key : reverseOrbits.keySet()) {
|
||||
count += countIndirectOrbits(key);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private int countIndirectOrbits(String key) {
|
||||
var count = 0;
|
||||
var currentKey = reverseOrbits.get(key);
|
||||
while (currentKey != null) {
|
||||
currentKey = reverseOrbits.get(currentKey);
|
||||
if (currentKey != null) count++;
|
||||
else return count;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private List<String> pathToCom(String key) {
|
||||
var path = new ArrayList<String>();
|
||||
var currentKey = reverseOrbits.get(key);
|
||||
path.add(currentKey);
|
||||
while (currentKey != null) {
|
||||
currentKey = reverseOrbits.get(currentKey);
|
||||
if (currentKey == null) return path;
|
||||
else path.add(currentKey);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
private int part1() {
|
||||
for (var line : input) {
|
||||
var split = line.split("\\)");
|
||||
reverseOrbits.put(split[1], split[0]);
|
||||
}
|
||||
return countDirectOrbits() + countIndirectOrbits();
|
||||
}
|
||||
|
||||
private int part2() {
|
||||
var sanPath = pathToCom("SAN");
|
||||
var youPath = pathToCom("YOU");
|
||||
|
||||
var common = new LinkedHashSet<>(sanPath);
|
||||
common.retainAll(youPath);
|
||||
|
||||
String closestCommon = (String) common.toArray()[0];
|
||||
return sanPath.indexOf(closestCommon) + youPath.indexOf(closestCommon);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package be.vandewalleh.aoc.geometry;
|
||||
|
||||
public enum Direction2D {
|
||||
Up(0, -1), Down(0, 1), Right(1, 0), Left(-1, 0);
|
||||
|
||||
public final Point2D point;
|
||||
|
||||
Direction2D(int x, int y) {
|
||||
this.point = new Point2D(x, y);
|
||||
}
|
||||
|
||||
public static Direction2D from(char direction) {
|
||||
switch (direction) {
|
||||
case 'U' -> {
|
||||
return Direction2D.Up;
|
||||
}
|
||||
case 'D' -> {
|
||||
return Direction2D.Down;
|
||||
}
|
||||
case 'R' -> {
|
||||
return Direction2D.Right;
|
||||
}
|
||||
case 'L' -> {
|
||||
return Direction2D.Left;
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Unexpected value: " + direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package be.vandewalleh.aoc.geometry;
|
||||
|
||||
public record Point2D(int x, int y) {
|
||||
public static Point2D origin = new Point2D(0, 0);
|
||||
|
||||
public int manhattanDistance() {
|
||||
return Math.abs(x) + Math.abs(y);
|
||||
}
|
||||
|
||||
public Point2D translate(Point2D other) {
|
||||
return new Point2D(this.x + other.x, this.y + other.y);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
package be.vandewalleh.aoc.intcode;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
|
||||
public class IntCodeInterpreter {
|
||||
private final Deque<Long> outputs = new ArrayDeque<>();
|
||||
private final long[] memory;
|
||||
|
||||
public IntCodeInterpreter(long[] memory) {
|
||||
var copy = new long[memory.length];
|
||||
System.arraycopy(memory, 0, copy, 0, memory.length);
|
||||
this.memory = copy;
|
||||
}
|
||||
private long input;
|
||||
|
||||
public IntCodeInterpreter(int[] memory) {
|
||||
this.memory = Arrays.stream(memory).asLongStream().toArray();
|
||||
@@ -23,26 +21,95 @@ public class IntCodeInterpreter {
|
||||
memory[2] = verb;
|
||||
}
|
||||
|
||||
public void setInput(long input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public long getOutput() {
|
||||
return memory[0];
|
||||
}
|
||||
|
||||
// private ?
|
||||
public Deque<Long> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
private long readArgument(Mode mode, long param) {
|
||||
switch (mode) {
|
||||
case Positional -> {
|
||||
return memory[(int) param];
|
||||
}
|
||||
case Immediate -> {
|
||||
return param;
|
||||
}
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeArgument(long param, long value) {
|
||||
memory[(int) param] = value;
|
||||
}
|
||||
|
||||
private Mode[] modes(long instruction) {
|
||||
var str = String.format("%5d", instruction).replace(' ', '0');
|
||||
return new Mode[]{
|
||||
Mode.of(str.charAt(2)),
|
||||
Mode.of(str.charAt(1)),
|
||||
Mode.of(str.charAt(0))
|
||||
};
|
||||
}
|
||||
|
||||
public void run() {
|
||||
var pointer = 0;
|
||||
|
||||
loop:
|
||||
while (true) {
|
||||
var optionalOpCode = OpCode.from((int) memory[pointer]);
|
||||
var opCode = optionalOpCode.orElseThrow(() -> new IllegalArgumentException("Invalid OpCode"));
|
||||
var jumped = false;
|
||||
var instruction = memory[pointer];
|
||||
var opCode = OpCode.from(((int) instruction) % 100);
|
||||
var args = Arrays.copyOfRange(memory, pointer + 1, pointer + opCode.params + 1);
|
||||
var modes = modes(instruction);
|
||||
switch (opCode) {
|
||||
case Add -> memory[(int) args[2]] = memory[(int) args[0]] + memory[(int) args[1]];
|
||||
case Multiply -> memory[(int) args[2]] = memory[(int) args[0]] * memory[(int) args[1]];
|
||||
case Add -> {
|
||||
var value = readArgument(modes[0], args[0]) + readArgument(modes[1], args[1]);
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case Multiply -> {
|
||||
var value = readArgument(modes[0], args[0]) * readArgument(modes[1], args[1]);
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case In -> {
|
||||
writeArgument(args[0], input);
|
||||
}
|
||||
case Out -> {
|
||||
outputs.push(readArgument(modes[0], args[0]));
|
||||
}
|
||||
case JumpIfTrue -> {
|
||||
if (readArgument(modes[0], args[0]) != 0) {
|
||||
pointer = (int) readArgument(modes[1], args[1]);
|
||||
jumped = true;
|
||||
}
|
||||
}
|
||||
case JumpIfFalse -> {
|
||||
if (readArgument(modes[0], args[0]) == 0) {
|
||||
pointer = (int) readArgument(modes[1], args[1]);
|
||||
jumped = true;
|
||||
}
|
||||
}
|
||||
case LessThan -> {
|
||||
var value = readArgument(modes[0], args[0]) < readArgument(modes[1], args[1]) ? 1 : 0;
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case Equals -> {
|
||||
var value = readArgument(modes[0], args[0]) == readArgument(modes[1], args[1]) ? 1 : 0;
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case Halt -> {
|
||||
break loop;
|
||||
}
|
||||
|
||||
}
|
||||
pointer += opCode.params + 1;
|
||||
if (!jumped) pointer += opCode.params + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package be.vandewalleh.aoc.intcode;
|
||||
|
||||
public enum Mode {
|
||||
Positional, Immediate;
|
||||
|
||||
public static Mode of(char representation) {
|
||||
if (representation == '0') return Mode.Positional;
|
||||
else if (representation == '1') return Mode.Immediate;
|
||||
else throw new IllegalArgumentException("Unsupported Mode " + representation);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,14 @@ import java.util.Optional;
|
||||
public enum OpCode {
|
||||
Add(1, 3),
|
||||
Multiply(2, 3),
|
||||
Halt(99, 0);
|
||||
Halt(99, 0),
|
||||
In(3, 1),
|
||||
Out(4, 1),
|
||||
JumpIfTrue(5, 2),
|
||||
JumpIfFalse(6, 2),
|
||||
LessThan(7, 3),
|
||||
Equals(8, 3),
|
||||
;
|
||||
|
||||
public final int value;
|
||||
public final int params;
|
||||
@@ -15,10 +22,10 @@ public enum OpCode {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public static Optional<OpCode> from(int value) {
|
||||
public static OpCode from(int value) {
|
||||
for (OpCode opCode : OpCode.values()) {
|
||||
if (opCode.value == value) return Optional.of(opCode);
|
||||
if (opCode.value == value) return opCode;
|
||||
}
|
||||
return Optional.empty();
|
||||
throw new IllegalArgumentException("Unsupported OpCode " + value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user