1
0

Compare commits

38 Commits

Author SHA1 Message Date
hubert 3906d6ef72 Day17 2021 in nim 2021-12-18 00:51:38 +01:00
hubert 1d745a0855 Add Input.findAll 2021-12-15 01:07:10 +01:00
hubert 3550f65914 Create Counter class 2021-12-15 00:51:15 +01:00
hubert 20f20a3179 Clean day14 2021-12-14 22:57:05 +01:00
hubert eff95027de Day14 2021 2021-12-14 22:46:54 +01:00
hubert 76e670770e Use fold for folds 2021-12-13 20:10:52 +01:00
hubert e014b32ab4 Day13 2021 2021-12-13 19:50:47 +01:00
hubert ed3c7f3a04 Day12 2021 2021-12-12 15:24:22 +01:00
hubert 73235b3e44 Clean 2021-12-11 16:44:11 +01:00
hubert 118b56e5f3 Day11 2021 2021-12-11 12:25:47 +01:00
hubert b5e8ea0a3b aaa 2021-12-10 20:14:33 +01:00
hubert 57f4a97627 Day10 2021 2021-12-10 19:49:36 +01:00
hubert 20e2555470 Day09 2021 2021-12-09 12:49:09 +01:00
hubert 998c523971 Day08 2021 2021-12-08 19:18:09 +01:00
hubert 7de77107e6 Day07 2021 2021-12-07 06:47:28 +01:00
hubert 5bb873bcc5 Day06 2021 2021-12-06 12:34:18 +01:00
hubert c3e8e6320e Day05 2021 2021-12-05 15:47:12 +01:00
hubert 81a488aaee Disable tests without answers 2021-12-05 14:50:27 +01:00
hubert 5c94aed258 clean 2021-12-04 13:45:01 +01:00
hubert 97334d34eb Day04 2021 2021-12-04 12:10:44 +01:00
hubert 399d894c68 Simplify 2021-12-03 12:46:09 +01:00
hubert 782fccc572 Day03 2021 2021-12-03 12:35:01 +01:00
hubert 811a6a0af0 things 2021-12-03 12:34:02 +01:00
hubert b9a8e7585b Day02 2021 2021-12-02 10:08:30 +01:00
hubert 15b11a191d Add test 2021-12-01 22:27:53 +01:00
hubert 3e09eee5b7 Add some magic 2021-12-01 19:47:11 +01:00
hubert 322f8eb45a Update things 2021-12-01 19:32:38 +01:00
hubert ccfcf5a259 Day01 2021 2021-12-01 12:42:10 +01:00
hubert ae327a4928 Day 3-6 2019 2020-12-31 00:52:18 +01:00
hubert 4fef41464e Day02 2019 2020-12-30 19:20:45 +01:00
hubert 4a90257257 Prepare for other years 2020-12-30 18:01:52 +01:00
hubert 522618d106 Day25 2020-12-30 14:42:29 +01:00
hubert 0ad5dac997 Clean 2020-12-29 23:01:35 +01:00
hubert 7a871771bb Day 20 finally 2020-12-29 22:34:13 +01:00
hubert c11231307f Day20 part2 grid assembly 2020-12-29 21:09:51 +01:00
hubert e72f71c1bf Use custom class for faster hashcode 2020-12-24 16:17:24 +01:00
hubert 5d73f12e43 Day24 part2 2020-12-24 15:55:11 +01:00
hubert 23cb05ad27 Day24 part1 2020-12-24 12:48:30 +01:00
155 changed files with 10329 additions and 787 deletions
+14
View File
@@ -0,0 +1,14 @@
plugins {
id("java-convention")
}
dependencies {
implementation(project(":utils"))
annotationProcessor(Libs.Micronaut.processor)
implementation(Libs.eclipseCollections)
testImplementation(Libs.Jmh.core)
testAnnotationProcessor(Libs.Jmh.processor)
}
@@ -0,0 +1,47 @@
package be.vandewalleh.aoc;
import be.vandewalleh.aoc.utils.factory.Days;
import be.vandewalleh.aoc.utils.input.Day;
import be.vandewalleh.aoc.utils.input.Lines;
@Day(1)
public class Day01 {
public static void main(String[] args) {
var day = Days.createDay(Day01.class);
System.out.println(day.part1());
System.out.println(day.part2());
}
private final int[] input;
public Day01(@Lines int[] input) {
this.input = input;
}
private int fuel(int mass) {
return (mass / 3) - 2;
}
public int part1() {
var total = 0;
for (var mass : input) {
total += fuel(mass);
}
return total;
}
public int part2() {
var total = 0;
for (var mass : input) {
int fuel = fuel(mass);
total += fuel;
while (true) {
fuel = fuel(fuel);
if (fuel <= 0) break;
total += fuel;
}
}
return total;
}
}
@@ -0,0 +1,43 @@
package be.vandewalleh.aoc;
import be.vandewalleh.aoc.intcode.IntCodeInterpreter;
import be.vandewalleh.aoc.utils.factory.Days;
import be.vandewalleh.aoc.utils.input.Csv;
import be.vandewalleh.aoc.utils.input.Day;
@Day(2)
public class Day02 {
public static void main(String[] args) {
var day = Days.createDay(Day02.class);
System.out.println(day.part1());
System.out.println(day.part2());
}
private final int[] input;
public Day02(@Csv int[] input) {
this.input = input;
}
private long runInterpreterWith(int noun, int verb) {
var interpreter = new IntCodeInterpreter(input);
interpreter.setNoun(noun);
interpreter.setVerb(verb);
interpreter.run();
return interpreter.getOutput();
}
public long part1() {
return runInterpreterWith(12, 2);
}
public int part2() {
for (var noun = 0; noun < 99; noun++) {
for (var verb = 0; verb < 99; verb++) {
if (runInterpreterWith(noun, verb) == 19690720L) return 100 * noun + verb;
}
}
return -1;
}
}
@@ -0,0 +1,63 @@
package be.vandewalleh.aoc;
import be.vandewalleh.aoc.geometry.Direction2D;
import be.vandewalleh.aoc.geometry.Point2D;
import be.vandewalleh.aoc.utils.factory.Days;
import be.vandewalleh.aoc.utils.input.Day;
import be.vandewalleh.aoc.utils.input.Lines;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@Day(3)
public class Day03 {
public static void main(String[] args) {
var day = Days.createDay(Day03.class);
System.out.println(day.part1());
System.out.println(day.part2());
}
private final String[] wireA;
private final String[] wireB;
public Day03(@Lines List<String> input) {
this.wireA = input.get(0).split(",");
this.wireB = input.get(1).split(",");
}
private List<Point2D> path(String[] wire) {
var points = new ArrayList<Point2D>();
var point = Point2D.origin;
for (var section : wire) {
var direction = Direction2D.from(section.charAt(0));
var count = Integer.parseInt(section.substring(1));
for (int i = 0; i < count; i++) {
point = point.translate(direction.point);
points.add(point);
}
}
return points;
}
private int part1() {
var pathA = path(wireA);
var pathB = path(wireB);
var intersections = new HashSet<>(pathA);
intersections.retainAll(pathB);
return intersections.stream().mapToInt(Point2D::manhattanDistance).min().orElse(-1);
}
private int part2() {
var pathA = path(wireA);
var pathB = path(wireB);
var intersections = new HashSet<>(pathA);
intersections.retainAll(pathB);
return intersections.stream().mapToInt(p -> pathA.indexOf(p) + pathB.indexOf(p) + 2).min().orElse(-1);
}
}
@@ -0,0 +1,80 @@
package be.vandewalleh.aoc;
import be.vandewalleh.aoc.utils.factory.Days;
import be.vandewalleh.aoc.utils.input.Day;
import be.vandewalleh.aoc.utils.input.Text;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
@Day(4)
public class Day04 {
public static void main(String[] args) {
var day = Days.createDay(Day04.class);
System.out.println(day.part1());
System.out.println(day.part2());
}
private final int min;
private final int max;
public Day04(@Text String input) {
var spl = input.split("-", 2);
min = Integer.parseInt(spl[0]);
max = Integer.parseInt(spl[1]);
}
private boolean isNotDecreasing(int[] ints) {
for (int i = 0; i < 5; i++) {
int a = ints[i], b = ints[i + 1];
if (b < a) return false;
}
return true;
}
private boolean hasPair(int[] ints) {
for (int i = 0; i < 5; i++) {
int a = ints[i], b = ints[i + 1];
if (a == b) return true;
}
return false;
}
private boolean hasGroup(int[] ints) {
var occurrences = new int[10];
for (int i = 0; i < 5; i++) {
int a = ints[i], b = ints[i + 1];
if (a == b) occurrences[a]++;
}
return Arrays.stream(occurrences).anyMatch(e -> e == 1);
}
private Stream<int[]> intStream() {
return IntStream.rangeClosed(min, max)
.mapToObj(String::valueOf)
.map(String::toCharArray)
.map(e -> {
var ints = new int[6];
for (int i = 0; i < 6; i++) {
ints[i] = Integer.parseInt(String.valueOf(e[i]));
}
return ints;
});
}
private long part1() {
return intStream()
.filter(this::isNotDecreasing)
.filter(this::hasPair)
.count();
}
private long part2() {
return intStream()
.filter(this::isNotDecreasing)
.filter(this::hasGroup)
.count();
}
}
@@ -0,0 +1,36 @@
package be.vandewalleh.aoc;
import be.vandewalleh.aoc.intcode.IntCodeInterpreter;
import be.vandewalleh.aoc.utils.factory.Days;
import be.vandewalleh.aoc.utils.input.Csv;
import be.vandewalleh.aoc.utils.input.Day;
@Day(5)
public class Day05 {
public static void main(String[] args) {
var day = Days.createDay(Day05.class);
System.out.println(day.part1());
System.out.println(day.part2());
}
private final int[] input;
public Day05(@Csv int[] input) {
this.input = input;
}
private Long part1() {
var interpreter = new IntCodeInterpreter(input);
interpreter.setInput(1);
interpreter.run();
return interpreter.getOutputs().peek();
}
private Long part2() {
var interpreter = new IntCodeInterpreter(input);
interpreter.setInput(5);
interpreter.run();
return interpreter.getOutputs().peek();
}
}
@@ -0,0 +1,80 @@
package be.vandewalleh.aoc;
import be.vandewalleh.aoc.utils.factory.Days;
import be.vandewalleh.aoc.utils.input.Day;
import be.vandewalleh.aoc.utils.input.Lines;
import java.util.*;
@Day(6)
public class Day06 {
public static void main(String[] args) {
var day = Days.createDay(Day06.class);
System.out.println(day.part1());
System.out.println(day.part2());
}
private final List<String> input;
public Day06(@Lines List<String> input) {
this.input = input;
}
private final Map<String, String> reverseOrbits = new HashMap<>();
private int countDirectOrbits() {
return reverseOrbits.size();
}
private int countIndirectOrbits() {
var count = 0;
for (var key : reverseOrbits.keySet()) {
count += countIndirectOrbits(key);
}
return count;
}
private int countIndirectOrbits(String key) {
var count = 0;
var currentKey = reverseOrbits.get(key);
while (currentKey != null) {
currentKey = reverseOrbits.get(currentKey);
if (currentKey != null) count++;
else return count;
}
return -1;
}
private List<String> pathToCom(String key) {
var path = new ArrayList<String>();
var currentKey = reverseOrbits.get(key);
path.add(currentKey);
while (currentKey != null) {
currentKey = reverseOrbits.get(currentKey);
if (currentKey == null) return path;
else path.add(currentKey);
}
return path;
}
private int part1() {
for (var line : input) {
var split = line.split("\\)");
reverseOrbits.put(split[1], split[0]);
}
return countDirectOrbits() + countIndirectOrbits();
}
private int part2() {
var sanPath = pathToCom("SAN");
var youPath = pathToCom("YOU");
var common = new LinkedHashSet<>(sanPath);
common.retainAll(youPath);
String closestCommon = (String) common.toArray()[0];
return sanPath.indexOf(closestCommon) + youPath.indexOf(closestCommon);
}
}
@@ -0,0 +1,29 @@
package be.vandewalleh.aoc.geometry;
public enum Direction2D {
Up(0, -1), Down(0, 1), Right(1, 0), Left(-1, 0);
public final Point2D point;
Direction2D(int x, int y) {
this.point = new Point2D(x, y);
}
public static Direction2D from(char direction) {
switch (direction) {
case 'U' -> {
return Direction2D.Up;
}
case 'D' -> {
return Direction2D.Down;
}
case 'R' -> {
return Direction2D.Right;
}
case 'L' -> {
return Direction2D.Left;
}
default -> throw new IllegalArgumentException("Unexpected value: " + direction);
}
}
}
@@ -0,0 +1,13 @@
package be.vandewalleh.aoc.geometry;
public record Point2D(int x, int y) {
public static Point2D origin = new Point2D(0, 0);
public int manhattanDistance() {
return Math.abs(x) + Math.abs(y);
}
public Point2D translate(Point2D other) {
return new Point2D(this.x + other.x, this.y + other.y);
}
}
@@ -0,0 +1,115 @@
package be.vandewalleh.aoc.intcode;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
public class IntCodeInterpreter {
private final Deque<Long> outputs = new ArrayDeque<>();
private final long[] memory;
private long input;
public IntCodeInterpreter(int[] memory) {
this.memory = Arrays.stream(memory).asLongStream().toArray();
}
public void setNoun(long noun) {
memory[1] = noun;
}
public void setVerb(long verb) {
memory[2] = verb;
}
public void setInput(long input) {
this.input = input;
}
public long getOutput() {
return memory[0];
}
// private ?
public Deque<Long> getOutputs() {
return outputs;
}
private long readArgument(Mode mode, long param) {
switch (mode) {
case Positional -> {
return memory[(int) param];
}
case Immediate -> {
return param;
}
default -> throw new IllegalArgumentException();
}
}
private void writeArgument(long param, long value) {
memory[(int) param] = value;
}
private Mode[] modes(long instruction) {
var str = String.format("%5d", instruction).replace(' ', '0');
return new Mode[]{
Mode.of(str.charAt(2)),
Mode.of(str.charAt(1)),
Mode.of(str.charAt(0))
};
}
public void run() {
var pointer = 0;
loop:
while (true) {
var jumped = false;
var instruction = memory[pointer];
var opCode = OpCode.from(((int) instruction) % 100);
var args = Arrays.copyOfRange(memory, pointer + 1, pointer + opCode.params + 1);
var modes = modes(instruction);
switch (opCode) {
case Add -> {
var value = readArgument(modes[0], args[0]) + readArgument(modes[1], args[1]);
writeArgument(args[2], value);
}
case Multiply -> {
var value = readArgument(modes[0], args[0]) * readArgument(modes[1], args[1]);
writeArgument(args[2], value);
}
case In -> {
writeArgument(args[0], input);
}
case Out -> {
outputs.push(readArgument(modes[0], args[0]));
}
case JumpIfTrue -> {
if (readArgument(modes[0], args[0]) != 0) {
pointer = (int) readArgument(modes[1], args[1]);
jumped = true;
}
}
case JumpIfFalse -> {
if (readArgument(modes[0], args[0]) == 0) {
pointer = (int) readArgument(modes[1], args[1]);
jumped = true;
}
}
case LessThan -> {
var value = readArgument(modes[0], args[0]) < readArgument(modes[1], args[1]) ? 1 : 0;
writeArgument(args[2], value);
}
case Equals -> {
var value = readArgument(modes[0], args[0]) == readArgument(modes[1], args[1]) ? 1 : 0;
writeArgument(args[2], value);
}
case Halt -> {
break loop;
}
}
if (!jumped) pointer += opCode.params + 1;
}
}
}
@@ -0,0 +1,11 @@
package be.vandewalleh.aoc.intcode;
public enum Mode {
Positional, Immediate;
public static Mode of(char representation) {
if (representation == '0') return Mode.Positional;
else if (representation == '1') return Mode.Immediate;
else throw new IllegalArgumentException("Unsupported Mode " + representation);
}
}
@@ -0,0 +1,29 @@
package be.vandewalleh.aoc.intcode;
public enum OpCode {
Add(1, 3),
Multiply(2, 3),
Halt(99, 0),
In(3, 1),
Out(4, 1),
JumpIfTrue(5, 2),
JumpIfFalse(6, 2),
LessThan(7, 3),
Equals(8, 3),
;
public final int value;
public final int params;
OpCode(int value, int params) {
this.value = value;
this.params = params;
}
public static OpCode from(int value) {
for (OpCode opCode : OpCode.values()) {
if (opCode.value == value) return opCode;
}
throw new IllegalArgumentException("Unsupported OpCode " + value);
}
}
+100
View File
@@ -0,0 +1,100 @@
132791
78272
114679
60602
59038
69747
61672
147972
92618
70186
125826
61803
78112
124864
58441
113062
105389
125983
90716
75544
148451
73739
127762
146660
128747
148129
138635
80095
60241
145455
98730
59139
146828
113550
91682
107415
129207
147635
104583
102245
73446
148657
96364
52033
69964
63609
98207
73401
65511
115034
126179
96664
85394
128472
79017
93222
55267
102446
133150
148985
95325
57713
77370
60879
111977
99362
91581
55201
137670
127159
128324
77217
86378
112847
108265
80355
75650
106222
67793
113891
74508
139463
69972
122753
135854
127770
101085
98304
61451
146719
61225
60468
83613
137436
126303
78759
70081
110671
113234
111563
+1
View File
@@ -0,0 +1 @@
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,6,1,19,1,5,19,23,2,6,23,27,1,27,5,31,2,9,31,35,1,5,35,39,2,6,39,43,2,6,43,47,1,5,47,51,2,9,51,55,1,5,55,59,1,10,59,63,1,63,6,67,1,9,67,71,1,71,6,75,1,75,13,79,2,79,13,83,2,9,83,87,1,87,5,91,1,9,91,95,2,10,95,99,1,5,99,103,1,103,9,107,1,13,107,111,2,111,10,115,1,115,5,119,2,13,119,123,1,9,123,127,1,5,127,131,2,131,6,135,1,135,5,139,1,139,6,143,1,143,6,147,1,2,147,151,1,151,5,0,99,2,14,0,0
+2
View File
@@ -0,0 +1,2 @@
R1000,U371,R195,U136,R804,U805,L450,U211,R768,U768,L548,U354,L736,U431,L152,U658,L670,D262,L277,U136,L290,U939,R501,U550,L931,D839,R335,D492,L25,U80,R878,U355,R653,U186,R423,D485,L793,D259,L739,U679,R508,D269,R432,D761,R97,D461,L675,U958,L58,U348,L719,D271,R144,U849,R384,U72,L84,U493,R947,U30,L356,D442,R327,U646,R825,U718,L329,D173,L949,D345,L971,D830,L93,U506,R245,D376,R322,D105,L604,D60,R298,D959,L165,D423,R180,D527,R956,D944,R785,U641,L794,D182,R975,D719,L166,U974,L224,U243,L666,U706,R796,D600,L856,D913,L988,D993,L259,U351,R487,D424,L335,U910,L437,D180,R621,D3,R878,D188,R254,D393,L727,U829,R352,U958,L327,D158,L854,D17,R143,D454,R889,D265,L345,U784,R35,D129,R77,U117,R951,D980,L866,U646,R242,D603,L562,U727,L496,U328,L380,D504,R644,U803,L530,D546,R328,D373,L489,U454,R74,D908,R366,U94,R604,D482,L573,D27,R943,U497,L782,D267,L391,U49,R528,D58,R155,D529,R227,D998,R558,D891,R224,U843,R512,U34,R92,U404,R752,U946,L338,D880,L513,D28,L856,D444,L187,U532,L187,U669,L306,U259,R287,D442,R478,U576,R702,U336,L305,U701,L754,D277,R760,D863,L717,U196,L221,U101,L334,D156,L961,D810,L67,D716,L457,D44,L505,D724,R716,D660,L36,D338,R54,U424,R730,U18,L65,D133,R149,U374,R356,D989,R519,U593,L444,D270,R328,U167,L748,D797,L434,U751,R444,D71,R158,D530,L630,U147,R909,D994,L957,U521,L644,D579,R673,U191,R935,U237,R600,D321,L671,U961,L884,U378,R534,D46,R275,U845,R571,U245,L507,U273,R995,U408,L14,D799,L955,D534,R579,D94,R705,D391,R469,D381,R620,U162,R907,D826,R824,U167,L734,U922,L484
L1007,D620,R853,U77,L13,U473,L253,D410,R897,U464,L862,U281,L650,D470,R87,D204,L896,U670,L864,D950,L75,D320,R901,D785,L653,D225,L857,U616,L143,U940,L664,U131,L547,D745,R636,U569,L50,U454,R288,D254,L36,U377,L609,U929,L714,U85,L939,U923,L566,D280,R243,U948,R447,D7,R908,D151,R824,D432,R34,D81,L458,U745,L420,D982,L625,U910,L729,D274,R910,U322,L984,D88,L700,D349,L932,U510,R625,U88,L252,U785,L378,D101,R299,U66,L476,U696,R236,D46,R590,U157,R461,U305,L269,D487,L676,U467,R319,D524,R75,U65,L478,U861,L238,D716,R888,D12,L184,D578,R266,D226,L656,D172,L752,U124,L831,U810,L663,U538,R417,D770,L359,U1,R12,U791,L332,U272,R574,D942,L857,U447,R310,U342,L713,D258,R590,D585,R129,D115,R832,D967,R981,D159,R864,U423,R268,U519,L52,D493,R445,D657,R885,U166,R155,D264,R51,D632,R525,D875,R617,U898,L556,D386,L143,U278,L767,D389,R821,U869,R286,D90,R289,U54,R15,D764,R46,D674,R983,U49,R959,U779,R958,D247,R483,U156,L18,U12,L178,U540,L499,U487,L544,D336,R814,U267,R145,D135,L920,D902,L933,D507,L997,U361,L577,U425,L773,D782,R117,U851,R998,U503,R902,U781,L161,U98,L653,U633,L91,U629,L138,D19,R147,D756,R364,D529,L764,U913,L118,U856,R774,D621,R151,U154,R737,D960,R86,U458,R991,D481,R560,D858,R223,D6,R931,D301,R552,D797,R284,U368,L967,D686,R940,U410,R137,D156,L6,U643,L445,D999,R888,D277,L852,U210,L777,D36,R103,D652,R120,D67,L642,D527,R913,D858,R69,D433,R864,U75,L531,U456,L664,D452,R801,U851,L824,D278,L526,U133,R200,U768,R15,U393,R982,U287,L38,D114,R86,U299,L819,D891,R379,D601,L244
+1
View File
@@ -0,0 +1 @@
272091-815432
+1
View File
@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1101,11,91,225,1002,121,77,224,101,-6314,224,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,223,1102,74,62,225,1102,82,7,224,1001,224,-574,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,28,67,225,1102,42,15,225,2,196,96,224,101,-4446,224,224,4,224,102,8,223,223,101,6,224,224,1,223,224,223,1101,86,57,225,1,148,69,224,1001,224,-77,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1101,82,83,225,101,87,14,224,1001,224,-178,224,4,224,1002,223,8,223,101,7,224,224,1,223,224,223,1101,38,35,225,102,31,65,224,1001,224,-868,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,1101,57,27,224,1001,224,-84,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,61,78,225,1001,40,27,224,101,-89,224,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,677,226,224,1002,223,2,223,1006,224,329,101,1,223,223,8,226,677,224,102,2,223,223,1005,224,344,101,1,223,223,1107,226,677,224,102,2,223,223,1006,224,359,101,1,223,223,1007,226,226,224,102,2,223,223,1006,224,374,101,1,223,223,7,677,677,224,102,2,223,223,1005,224,389,1001,223,1,223,108,677,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,226,226,224,102,2,223,223,1005,224,419,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,434,1001,223,1,223,1108,677,677,224,102,2,223,223,1006,224,449,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,464,101,1,223,223,1008,677,677,224,102,2,223,223,1005,224,479,101,1,223,223,1007,226,677,224,1002,223,2,223,1006,224,494,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,509,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,524,101,1,223,223,107,226,226,224,102,2,223,223,1006,224,539,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,554,1001,223,1,223,7,677,226,224,102,2,223,223,1006,224,569,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,584,101,1,223,223,1107,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,614,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,629,101,1,223,223,108,226,677,224,102,2,223,223,1005,224,644,1001,223,1,223,108,226,226,224,102,2,223,223,1005,224,659,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,674,1001,223,1,223,4,223,99,226
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
plugins {
id("kotlin-convention")
kotlin("kapt")
}
dependencies {
implementation(project(":utils"))
kapt(Libs.Micronaut.processor)
implementation(Libs.Slf4J.api)
runtimeOnly(Libs.Slf4J.simple)
implementation(Libs.eclipseCollections)
testImplementation(Libs.Jmh.core)
kaptTest(Libs.Jmh.processor)
}
@@ -1,14 +1,10 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
@Day(1)
class Day01(@Lines input: Input<IntArray>) {
private val items = input.value
class Day01(@Lines val items: IntArray) {
fun part1(): Int? {
items.forEach { a ->
items.forEach { b ->
@@ -31,7 +27,3 @@ class Day01(@Lines input: Input<IntArray>) {
}
fun main() = with(createDay<Day01>()) {
println(part1())
println(part2())
}
@@ -1,17 +1,15 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
data class PasswordEntry(val range: IntRange, val letter: Char, val password: String)
@Day(2)
class Day02(@Lines input: Input<List<String>>) {
class Day02(@Lines input: List<String>) {
private data class PasswordEntry(val range: IntRange, val letter: Char, val password: String)
private val regex = "^(\\d+)-(\\d+) ([a-z]): (.*)$".toRegex()
private val passwords = input.value.map {
private val passwords = input.map {
val (_, min, max, letter, password) = regex.find(it)!!.groupValues
PasswordEntry(min.toInt()..max.toInt(), letter[0], password)
}
@@ -22,8 +20,3 @@ class Day02(@Lines input: Input<List<String>>) {
(pwd[range.first - 1] == letter) xor (pwd[range.last - 1] == letter)
}
}
fun main() = with(createDay<Day02>()) {
println(part1())
println(part2())
}
@@ -1,17 +1,14 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
data class Slope(val x: Int, val y: Int)
@Day(3)
class Day03(@Lines val input: Input<List<String>>) {
class Day03(@Lines val input: List<String>) {
private data class Slope(val x: Int, val y: Int)
fun part1(slope: Slope = Slope(x = 3, y = 1)): Int {
val grid = input.value
private fun findSlope(slope: Slope): Int {
val grid = input
var trees = 0
var x = 0
var y = 0
@@ -28,6 +25,8 @@ class Day03(@Lines val input: Input<List<String>>) {
return trees
}
fun part1() = findSlope(Slope(x = 3, y = 1))
fun part2(): Long = listOf(
Slope(x = 1, y = 1),
Slope(x = 3, y = 1),
@@ -35,11 +34,6 @@ class Day03(@Lines val input: Input<List<String>>) {
Slope(x = 7, y = 1),
Slope(x = 1, y = 2),
)
.map { part1(it).toLong() }
.map { findSlope(it).toLong() }
.reduce { acc, trees -> acc * trees }
}
fun main() = with(createDay<Day03>()) {
println(part1())
println(part2())
}
@@ -1,17 +1,15 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Text
import be.vandewalleh.aoc.utils.input.createDay
typealias Entry = Pair<String, String>
typealias Entries = List<Entry>
private typealias Entry = Pair<String, String>
private typealias Entries = List<Entry>
@Day(4)
class Day04(@Text val input: Input<String>) {
class Day04(@Text val input: String) {
val entries = input.value.split("\n\n").map {
val entries = input.split("\n\n").map {
it.split(" ", "\n").map { it.split(":").let { (k, v) -> k to v } }
}
@@ -42,8 +40,3 @@ class Day04(@Text val input: Input<String>) {
fun part2() = entries.count { it.hasRequiredKeys() && it.all { it.isValid() } }
}
fun main() = with(createDay<Day04>()) {
println(part1())
println(part2())
}
@@ -1,14 +1,12 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
@Day(5)
class Day05(@Lines val input: Input<List<String>>) {
class Day05(@Lines val input: List<String>) {
private val ids = input.value.map {
private val ids = input.map {
it.replace("F", "0")
.replace("B", "1")
.replace("L", "0")
@@ -22,8 +20,3 @@ class Day05(@Lines val input: Input<List<String>>) {
.find { (a, b) -> b - a > 1 }!!
.first() + 1
}
fun main() = with(createDay<Day05>()) {
println(part1())
println(part2())
}
@@ -1,15 +1,13 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Text
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.impl.factory.primitive.CharBags
@Day(6)
class Day06(@Text val input: Input<String>) {
class Day06(@Text val input: String) {
private val groups = input.value.split("\n\n")
private val groups = input.split("\n\n")
fun part1() = groups.sumBy { it.replace("\n", "").toCharArray().toSet().size }
@@ -23,8 +21,3 @@ class Day06(@Text val input: Input<String>) {
}
}
fun main() = with(createDay<Day06>()) {
println(part1())
println(part2())
}
@@ -1,18 +1,16 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.api.factory.Stacks
import org.eclipse.collections.api.multimap.list.ImmutableListMultimap
import org.eclipse.collections.api.stack.MutableStack
import org.eclipse.collections.impl.factory.Multimaps
data class Bag(val count: Int, val color: String)
@Day(7)
class Day07(@Lines val input: Input<List<String>>) {
class Day07(@Lines val input: List<String>) {
private data class Bag(val count: Int, val color: String)
private val map: ImmutableListMultimap<String, Bag>
@@ -22,7 +20,7 @@ class Day07(@Lines val input: Input<List<String>>) {
val colorRegex = "^(\\w+ \\w+)".toRegex()
val requirementRegex = "(\\d+) (\\w+ \\w+) bag".toRegex()
for (line in input.value) {
for (line in input) {
val outerColor = colorRegex.find(line)!!.groupValues[1]
for (match in requirementRegex.findAll(line)) {
val (_, count, color) = match.groupValues
@@ -50,8 +48,3 @@ class Day07(@Lines val input: Input<List<String>>) {
fun part2() = bagSequence("shiny gold").sumBy { it.count }
}
fun main() = with(createDay<Day07>()) {
println(part1())
println(part2())
}
@@ -1,21 +1,24 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.impl.factory.primitive.IntLists
import org.eclipse.collections.impl.factory.primitive.IntSets
@Day(8)
class Day08(@Lines val input: Input<List<String>>) {
class Day08(@Lines val input: List<String>) {
private val instructions = input.value.map {
private val instructions = input.map {
val words = it.split(" ")
Instruction(Operation.valueOf(words[0].capitalize()), words[1].toInt())
}.toTypedArray()
fun part1() = run(instructions)
fun part1() = run(instructions).let {
when (it) {
is VmResult.Looped -> it.acc
is VmResult.Terminated -> it.acc
}
}
private fun run(instructions: Array<Instruction>): VmResult {
var acc = 0
@@ -41,7 +44,7 @@ class Day08(@Lines val input: Input<List<String>>) {
return VmResult.Looped(acc)
}
fun part2(): VmResult {
fun part2(): Int {
val possibleMutations = IntLists.mutable.empty()
instructions.forEachIndexed { i, e ->
if (e.operation == Operation.Jmp || e.operation == Operation.Nop) possibleMutations.add(i)
@@ -54,7 +57,7 @@ class Day08(@Lines val input: Input<List<String>>) {
}
val res = run(copy)
if (res is VmResult.Terminated) return res
if (res is VmResult.Terminated) return res.acc
}
error("No result found")
@@ -62,17 +65,11 @@ class Day08(@Lines val input: Input<List<String>>) {
}
enum class Operation { Acc, Jmp, Nop }
private enum class Operation { Acc, Jmp, Nop }
data class Instruction(val operation: Operation, val argument: Int)
private data class Instruction(val operation: Operation, val argument: Int)
sealed class VmResult {
private sealed class VmResult {
data class Looped(val acc: Int) : VmResult()
data class Terminated(val acc: Int) : VmResult()
}
fun main() {
val day = createDay<Day08>()
println(day.part1())
println(day.part2())
}
@@ -1,20 +1,16 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
@Day(9)
class Day09(@Lines val input: Input<LongArray>) {
class Day09(@Lines val input: LongArray) {
private var part1Result = 0L
fun part1(): Long? {
val longs = input.value
for (windowStart in 0 until longs.size - 26) {
val last = longs[windowStart + 25]
for (windowStart in 0 until input.size - 26) {
val last = input[windowStart + 25]
if (!isValid(windowStart, last)) {
part1Result = last
return last
@@ -27,8 +23,8 @@ class Day09(@Lines val input: Input<LongArray>) {
private fun isValid(windowStart: Int, last: Long): Boolean {
for (i in windowStart until windowStart + 25) {
for (j in windowStart + 1 until windowStart + 25) {
val f = input.value[i]
val s = input.value[j]
val f = input[i]
val s = input[j]
if (f + s == last && f != s) return true
}
}
@@ -38,10 +34,10 @@ class Day09(@Lines val input: Input<LongArray>) {
fun part2(): Long {
var size = 2
while (true) {
for (startIndex in input.value.indices) {
val lastIndex = input.value.size - 1 - size
for (startIndex in input.indices) {
val lastIndex = input.size - 1 - size
if (startIndex + size > lastIndex) break
val slice = input.value.sliceArray(startIndex..startIndex + size)
val slice = input.sliceArray(startIndex..startIndex + size)
if (slice.sum() == part1Result) return slice.minOrNull()!! + slice.maxOrNull()!!
}
size++
@@ -49,8 +45,3 @@ class Day09(@Lines val input: Input<LongArray>) {
}
}
fun main() = with(createDay<Day09>()) {
println(part1())
println(part2())
}
@@ -1,18 +1,16 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.api.list.primitive.MutableIntList
import org.eclipse.collections.impl.factory.primitive.IntLists
import org.eclipse.collections.impl.factory.primitive.IntLongMaps
@Day(10)
class Day10(@Lines val input: Input<IntArray>) {
class Day10(@Lines val input: IntArray) {
fun part1(): Int {
val sorted = IntLists.mutable.of(0, *input.value).apply {
val sorted = IntLists.mutable.of(0, *input).apply {
sortThis()
add(last + 3)
}.toArray().toList()
@@ -29,7 +27,7 @@ class Day10(@Lines val input: Input<IntArray>) {
}
fun part2(): Long {
val sorted: MutableIntList = IntLists.mutable.of(*input.value).apply { sortThis() }
val sorted: MutableIntList = IntLists.mutable.of(*input).apply { sortThis() }
val map = IntLongMaps.mutable.empty().apply {
put(0, 1L)
@@ -43,8 +41,3 @@ class Day10(@Lines val input: Input<IntArray>) {
}
}
fun main() = with(createDay<Day10>()) {
println(part1())
println(part2())
}
@@ -1,34 +1,32 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
typealias Seats = Array<CharArray>
private typealias Seats = Array<CharArray>
fun Seats.deepClone(): Seats = map { it.clone() }.toTypedArray()
private fun Seats.deepClone(): Seats = map { it.clone() }.toTypedArray()
operator fun Seats.get(x: Int, y: Int): Char = this[y][x]
operator fun Seats.set(x: Int, y: Int, value: Char) {
private operator fun Seats.get(x: Int, y: Int): Char = this[y][x]
private operator fun Seats.set(x: Int, y: Int, value: Char) {
this[y][x] = value
}
operator fun Seats.contains(xy: Pair<Int, Int>): Boolean {
private operator fun Seats.contains(xy: Pair<Int, Int>): Boolean {
val (x, y) = xy
return x in 0 until width && y in 0 until height
}
val Seats.width get() = first().size
val Seats.height get() = size
private val Seats.width get() = first().size
private val Seats.height get() = size
fun Seats.asGridString() = joinToString("\n") { it.joinToString("") }
fun Seats.countOccupied() = sumBy { it.count { it == '#' } }
private fun Seats.asGridString() = joinToString("\n") { it.joinToString("") }
private fun Seats.countOccupied() = sumBy { it.count { it == '#' } }
@Day(11)
class Day11(@Lines val input: Input<List<String>>) {
class Day11(@Lines val input: List<String>) {
private val seats: Seats = input.value.map { it.toCharArray() }.toTypedArray()
private val seats: Seats = input.map { it.toCharArray() }.toTypedArray()
private val directions = listOf(
-1 to -1,
@@ -116,8 +114,3 @@ class Day11(@Lines val input: Input<List<String>>) {
fun part2() = findLastRepeating(seats, ::progress2).countOccupied()
}
fun main() = with(createDay<Day11>()) {
println(part1())
println(part2())
}
@@ -1,13 +1,11 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import kotlin.math.abs
@Day(12)
class Day12(@Lines val input: Input<List<String>>) {
class Day12(@Lines val input: List<String>) {
fun part1(): Int {
var x = 0
@@ -16,7 +14,7 @@ class Day12(@Lines val input: Input<List<String>>) {
val dirs = listOf("N", "E", "S", "W")
input.value.forEach {
input.forEach {
val dir = it.take(1)
val steps = it.drop(1).toInt()
@@ -50,7 +48,7 @@ class Day12(@Lines val input: Input<List<String>>) {
var waypointX = 10
var waypointY = -1
input.value.forEach {
input.forEach {
val dir = it.take(1)
val steps = it.drop(1).toInt()
@@ -79,8 +77,3 @@ class Day12(@Lines val input: Input<List<String>>) {
return abs(x) + abs(y)
}
}
fun main() = with(createDay<Day12>()) {
println(part1())
println(part2())
}
@@ -1,20 +1,18 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import kotlin.math.abs
data class Bus(val index: Int, val id: Long)
private data class Bus(val index: Int, val id: Long)
@Day(13)
class Day13(@Lines val input: Input<List<String>>) {
class Day13(@Lines val input: List<String>) {
fun part1(): Int {
val id = input.value[0].toInt()
val id = input[0].toInt()
val (busId, min) = input.value[1]
val (busId, min) = input[1]
.splitToSequence(",")
.filterNot { it == "x" }
.map { it.toInt() }
@@ -29,7 +27,7 @@ class Day13(@Lines val input: Input<List<String>>) {
private fun lcm(a: Long, b: Long): Long = a / gcd(a, b) * b
fun part2(): Long {
val buses = input.value[1]
val buses = input[1]
.splitToSequence(",")
.mapIndexedNotNull { index, bus ->
if (bus == "x") null
@@ -48,8 +46,3 @@ class Day13(@Lines val input: Input<List<String>>) {
return t
}
}
fun main() = with(createDay<Day13>()) {
println(part1())
println(part2())
}
@@ -1,15 +1,13 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import kotlin.math.pow
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
import org.eclipse.collections.impl.factory.primitive.LongIntMaps
@Day(14)
class Day14(@Lines val input: Input<List<String>>) {
class Day14(@Lines val input: List<String>) {
private val memRe = "mem\\[(\\d+)] = (.*)$".toRegex()
@@ -20,7 +18,7 @@ class Day14(@Lines val input: Input<List<String>>) {
var currentMask: String = ""
for (line in input.value) {
for (line in input) {
if (line.startsWith("mask")) {
currentMask = line.removePrefix("mask = ")
} else {
@@ -46,7 +44,7 @@ class Day14(@Lines val input: Input<List<String>>) {
var currentMask = ""
for (line in input.value) {
for (line in input) {
if (line[1] == 'a') {
currentMask = line.substring(7)
} else {
@@ -93,8 +91,3 @@ class Day14(@Lines val input: Input<List<String>>) {
}
}
fun main() = with(createDay<Day14>()) {
println(part1())
println(part2())
}
@@ -2,16 +2,14 @@ package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Csv
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.createDay
import kotlin.math.abs
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps
@Day(15)
class Day15(@Csv val input: Input<IntArray>) {
class Day15(@Csv val input: IntArray) {
private fun run(until: Int): Int {
val start = input.value
val start = input
val map = IntObjectMaps.mutable.empty<IntArray>()
@@ -43,11 +41,3 @@ class Day15(@Csv val input: Input<IntArray>) {
fun part2() = run(until = 30000000)
}
fun main() {
// val input = Input(intArrayOf(3, 1, 2))
with(createDay<Day15>()) {
println(part1())
println(part2())
}
}
@@ -2,8 +2,6 @@ package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Groups
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.api.multimap.list.ListMultimap
import org.eclipse.collections.api.multimap.list.MutableListMultimap
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
@@ -11,11 +9,11 @@ import org.eclipse.collections.impl.factory.Multimaps
import org.eclipse.collections.impl.multimap.list.FastListMultimap
@Day(16)
class Day16(@Groups val input: Input<List<List<String>>>) {
class Day16(@Groups val input: List<List<String>>) {
private val rangesGroup = input.value[0]
private val myTicket = input.value[1][1]
private val nearbyTicketsGroup = input.value[2].drop(1)
private val rangesGroup = input[0]
private val myTicket = input[1][1]
private val nearbyTicketsGroup = input[2].drop(1)
private val rangeRe = "(\\d+)-(\\d+)".toRegex()
@@ -148,8 +146,3 @@ class Day16(@Groups val input: Input<List<List<String>>>) {
return rangesByName
}
}
fun main() = with(createDay<Day16>()) {
println(part1())
println(part2())
}
@@ -1,17 +1,15 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
data class Point(val x: Int, val y: Int, val z: Int)
data class Point4(val x: Int, val y: Int, val z: Int, val blah: Int)
private data class Point(val x: Int, val y: Int, val z: Int)
private data class Point4(val x: Int, val y: Int, val z: Int, val blah: Int)
enum class State { Active, Inactive }
private enum class State { Active, Inactive }
@Day(17)
class Day17(@Lines val input: Input<List<String>>) {
class Day17(@Lines val input: List<String>) {
fun part1(): Int {
val grid = parseGrid { x, y -> Point(x, y, 0) }
@@ -27,7 +25,7 @@ class Day17(@Lines val input: Input<List<String>>) {
private fun <T> parseGrid(pointFactory: (x: Int, y: Int) -> T): MutableMap<T, State> {
val grid = mutableMapOf<T, State>()
input.value.forEachIndexed { index, row ->
input.forEachIndexed { index, row ->
row.forEachIndexed { col, char ->
val state = if (char == '#') State.Active else State.Inactive
grid[pointFactory(index, col)] = state
@@ -87,8 +85,3 @@ class Day17(@Lines val input: Input<List<String>>) {
}
}
fun main() = with(createDay<Day17>()) {
println(part1())
println(part2())
}
@@ -1,16 +1,14 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import java.util.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
enum class Operator { Add, Multiply }
private enum class Operator { Add, Multiply }
operator fun Operator.invoke(a: Long, b: Long) = when (this) {
private operator fun Operator.invoke(a: Long, b: Long) = when (this) {
Operator.Add -> a + b
Operator.Multiply -> a * b
}
@@ -20,10 +18,10 @@ private inline fun Logger.debug(msg: () -> Any) {
}
@Day(18)
class Day18(@Lines val input: Input<List<String>>) {
class Day18(@Lines val input: List<String>) {
private val logger = LoggerFactory.getLogger("Day18")
private val lines = input.value.map { it.replace(" ", "") }
private val lines = input.map { it.replace(" ", "") }
private fun parseGroups(line: String): Map<Int, List<IntRange>> {
var depth = 0
@@ -170,8 +168,3 @@ class Day18(@Lines val input: Input<List<String>>) {
.reduce { t, u -> t + u }
.get()
}
fun main() = with(createDay<Day18>()) {
println(part1())
println(part2())
}
@@ -2,15 +2,12 @@ package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Groups
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.createDay
import java.util.*
import kotlin.collections.ArrayList
@Day(19)
class Day19(@Groups val input: Input<List<List<String>>>) {
private val rules = input.value[0]
private val messages = input.value[1]
class Day19(@Groups val input: List<List<String>>) {
private val rules = input[0]
private val messages = input[1]
sealed class Rule {
data class CharRule(val value: Char) : Rule()
@@ -56,8 +53,3 @@ class Day19(@Groups val input: Input<List<List<String>>>) {
}
}
fun main() = with(createDay<Day19>()) {
println(part1())
println(part2())
}
+202
View File
@@ -0,0 +1,202 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.days.geometry.Grid
import be.vandewalleh.aoc.days.geometry.gridOf
import be.vandewalleh.aoc.days.geometry.transformations
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Groups
import kotlin.math.sqrt
private typealias Tile = Grid<Char>
@Day(20)
class Day20(@Groups val input: List<List<String>>) {
private val tiles: Map<Int, Tile> = input
.map { it[0].let { it.substring(5 until it.indexOf(':')).toInt() } to it.drop(1) }
.associate { (id, tile) -> id to gridOf(tile) }
private fun Tile.allEdges() = listOf(edges(), edges().map { it.reversed() }).flatten()
private fun edgesMatch(a: Tile, b: Tile): Boolean {
val edges = b.allEdges()
return a.allEdges().any { a -> edges.any { a == it } }
}
private fun combine(tiles: List<Tile>) = sequence {
for (i in 0 until tiles.lastIndex) {
val a = tiles[i]
for (j in i + 1 until tiles.size) {
val b = tiles[j]
yield(a to b)
}
}
}
private fun tilesByNeighbourCount(): MutableMap<Int, MutableList<Tile>> {
val neighbours = combine(tiles.values.toList())
.filter { (a, b) -> edgesMatch(a, b) }
.map { it.toList() }
.flatten()
.groupBy { it }
.values
val map = mutableMapOf<Int, MutableList<Tile>>()
for (neighbour in neighbours) {
map.computeIfAbsent(neighbour.size) { mutableListOf() }.add(neighbour.first())
}
return map
}
fun part1() = tilesByNeighbourCount()[2]!!
.map { tile -> tiles.entries.find { it.value == tile }!!.key.toLong() }
.reduce { acc, id -> acc * id }
private fun neighboursCount(grid: Grid<*>, x: Int, y: Int): Int {
var neighboursCount = 2
if (x != 0 && x != grid.lastColumnIndex) neighboursCount++
if (y != 0 && y != grid.lastRowIndex) neighboursCount++
return neighboursCount
}
private fun isLeftOk(grid: Grid<Tile?>, x: Int, y: Int, candidate: Tile) = grid[x - 1, y]
?.let { left -> candidate.firstColumn() == left.lastColumn() }
?: true
private fun isTopOk(grid: Grid<Tile?>, x: Int, y: Int, candidate: Tile) = grid[x, y - 1]
?.let { top -> candidate.firstRow() == top.lastRow() }
?: true
private fun isBottomOk(grid: Grid<*>, x: Int, y: Int, candidate: Tile, neighbours: Map<Int, List<Tile>>) =
if (y == grid.lastRowIndex) true
else neighbours[neighboursCount(grid, x, y + 1)]!!
.filterNot { it == candidate }
.count { it.transformations().any { candidate.lastColumn() == it.firstColumn() } } == 1
private fun isRightOk(grid: Grid<*>, x: Int, y: Int, candidate: Tile, neighbours: Map<Int, List<Tile>>) =
if (x == grid.lastColumnIndex) true
else neighbours[neighboursCount(grid, x + 1, y)]!!
.filterNot { it == candidate }
.count { it.transformations().any { candidate.lastRow() == it.firstRow() } } == 1
private fun assembleGrid(): Grid<Tile?> {
val size = sqrt(tiles.size.toDouble()).toInt()
val grid: Grid<Tile?> = Grid(Array(size) { Array(size) { null } })
val neighbours: MutableMap<Int, MutableList<Tile>> = tilesByNeighbourCount()
for (y in 0 until grid.height) {
for (x in 0 until grid.width) {
val neighboursCount = neighboursCount(grid, x, y)
val candidates = neighbours[neighboursCount]!!
val conditions = mutableListOf<(Tile) -> Boolean>()
conditions += { isLeftOk(grid, x, y, it) }
conditions += { isTopOk(grid, x, y, it) }
// why is this condition needed ?
if (x == 0 && y == 0) {
conditions += { isBottomOk(grid, x, y, it, neighbours) }
conditions += { isRightOk(grid, x, y, it, neighbours) }
}
var found: Tile? = null
outer@ for (candidate in candidates) {
for (transform in candidate.transformations()) {
if (conditions.all { it(transform) }) {
found = transform
candidates.remove(candidate)
break@outer
}
}
}
check(found != null)
grid[x, y] = found
}
}
return grid
}
private fun removeGaps(grid: Grid<Tile?>) {
for (y in 0 until grid.height) {
for (x in 0 until grid.width) {
grid[x, y] = removeGaps(grid[x, y]!!)
}
}
}
private fun removeGaps(tile: Tile): Tile {
val oldData: ArrayList<ArrayList<Char>> = tile.data
val newData = ArrayList<ArrayList<Char>>(oldData.size - 2)
oldData.subList(1, oldData.size - 1).forEach { d ->
val l = ArrayList<Char>().apply {
addAll(d.subList(1, d.size - 1))
}
newData.add(l)
}
return Tile(newData)
}
private fun gridToTile(grid: Grid<Tile?>): Tile {
val newData = ArrayList<ArrayList<Char>>()
for (y in 0 until grid.height) {
val row = grid.row(y)
for (yy in 0 until row[0]!!.height) {
val combinedRow = ArrayList<Char>().also { newData.add(it) }
row.forEach { combinedRow.addAll(it!!.row(yy)) }
}
}
return Tile(newData)
}
private fun Tile.subGridData(startX: Int, startY: Int, width: Int, height: Int): List<List<Char>> {
val newData = ArrayList<ArrayList<Char>>()
for (y in startY until startY + height) {
val row = ArrayList<Char>().also { newData.add(it) }
for (x in startX until startX + width) {
row.add(this[x, y]!!)
}
}
return newData
}
private fun List<List<Char>>.isMonster(monster: List<List<Char>>): Boolean {
val monsterRe = monster.joinToString("") { it.joinToString("") }.replace(" ", ".").toRegex()
val str = this.joinToString("") { it.joinToString("") }
return monsterRe.matches(str)
}
fun part2(): Int {
val grid = assembleGrid()
removeGaps(grid)
val megaTile = gridToTile(grid)
val monster: List<List<Char>> = """
| # |
|# ## ## ###|
| # # # # # # |
""".trimMargin("|").lines().map { it.toCharArray().dropLast(1) }
val monsterWidth = monster[0].size
val monsterHeight = 3
val monsterSquares = monster.flatten().count { it == '#' }
val squares = megaTile.data.flatten().count { it == '#' }
for (g in megaTile.transformations()) {
var count = 0
for (y in 0 until g.lastRowIndex - monsterHeight) {
for (x in 0 until g.lastColumnIndex - monsterWidth) {
val subgrid = g.subGridData(x, y, monsterWidth, monsterHeight)
if (subgrid.isMonster(monster)) {
count++
}
}
}
if (count != 0) return squares - (count * monsterSquares)
}
error("No monsters found")
}
}
@@ -1,16 +1,14 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Lines
import be.vandewalleh.aoc.utils.input.createDay
import org.eclipse.collections.api.factory.Bags
import org.eclipse.collections.api.multimap.set.MutableSetMultimap
import org.eclipse.collections.impl.factory.Multimaps
@Day(21)
class Day21(@Lines val input: Input<List<String>>) {
private val foods = input.value.map { line ->
class Day21(@Lines val input: List<String>) {
private val foods = input.map { line ->
val parOpen = line.indexOf('(')
val ingredients = line.substring(0 until parOpen - 1).split(" ")
val allergens = line.substring(parOpen + 1 until line.length - 1).removePrefix("contains ").split(", ")
@@ -57,8 +55,3 @@ class Day21(@Lines val input: Input<List<String>>) {
return map
}
}
fun main() = with(createDay<Day21>()) {
println(part1())
println(part2())
}
@@ -2,15 +2,13 @@ package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Groups
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.createDay
data class PlayedGame(val a: List<Int>, val b: List<Int>)
private data class PlayedGame(val a: List<Int>, val b: List<Int>)
@Day(22)
class Day22(@Groups val input: Input<List<List<String>>>) {
private val one = input.value[0].drop(1).map { it.toInt() }
private val two = input.value[1].drop(1).map { it.toInt() }
class Day22(@Groups val input: List<List<String>>) {
private val one = input[0].drop(1).map { it.toInt() }
private val two = input[1].drop(1).map { it.toInt() }
fun part1(): Long {
val oneDeque = ArrayDeque(one)
@@ -76,9 +74,3 @@ class Day22(@Groups val input: Input<List<List<String>>>) {
return if (one.isEmpty()) 2 else 1
}
}
fun main() = with(createDay<Day22>()) {
println(part1())
println(part2())
}
@@ -1,13 +1,11 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.Text
import be.vandewalleh.aoc.utils.input.createDay
@Day(23)
class Day23(@Text val input: Input<String>) {
private val cups = input.value.toCharArray().map { it.toString().toInt() }
class Day23(@Text val input: String) {
private val cups = input.toCharArray().map { it.toString().toInt() }
private fun <T> ringSequence(head: Ring.Node<T>) = generateSequence(head) { it.next }
@@ -111,8 +109,3 @@ class Day23(@Text val input: Input<String>) {
return current.next
}
}
fun main() = with(createDay<Day23>()) {
println(part1())
println(part2())
}
+65
View File
@@ -0,0 +1,65 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Lines
import org.eclipse.collections.api.bag.Bag
import org.eclipse.collections.api.bag.MutableBag
import org.eclipse.collections.api.factory.Bags
@Day(24)
class Day24(@Lines val input: List<String>) {
private data class HexPoint(val x: Int, val y: Int, val z: Int) {
fun translate(other: HexPoint) = HexPoint(this.x + other.x, this.y + other.y, this.z + other.z)
}
private enum class Direction(vararg coordinates: Int) {
E(1, -1, 0),
SE(0, -1, 1),
SW(-1, 0, 1),
W(-1, 1, 0),
NW(0, 1, -1),
NE(1, 0, -1);
val coordinates = HexPoint(coordinates[0], coordinates[1], coordinates[2])
}
private fun parseTile(line: String) = "e|se|sw|w|nw|ne".toRegex()
.findAll(line)
.flatMap { it.groupValues }
.map { Direction.valueOf(it.toUpperCase()) }
.toList()
private val tiles = input.map { parseTile(it) }.map {
it.map { it.coordinates }.reduce { acc, ints -> acc.translate(ints) }
}
fun part1() = Bags.immutable.ofAll(tiles).selectBlacks().size()
private fun Bag<HexPoint>.selectBlacks() = selectByOccurrences { it % 2 == 1 }
private fun HexPoint.adjacents() = Direction.values().map { this.translate(it.coordinates) }
// black -> odd
// white -> even || not in bag -> !in black
private fun day(bag: MutableBag<HexPoint>) {
val blacks = bag.selectBlacks().toSet()
val all = (bag + bag.flatMap { it.adjacents() }).toSet()
for (tile in all) {
val adjacents = tile.adjacents()
val adjacentBlacks = adjacents.count { it in blacks }
val isBlack = tile in blacks
if (isBlack && (adjacentBlacks == 0 || adjacentBlacks > 2)) bag.setOccurrences(tile, 2)
else if (!isBlack && adjacentBlacks == 2) bag.setOccurrences(tile, 1)
}
}
fun part2(): Int {
val bag = Bags.mutable.ofAll(tiles)
repeat(100) { day(bag) }
return bag.selectBlacks().size()
}
}
+44
View File
@@ -0,0 +1,44 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Day
import be.vandewalleh.aoc.utils.input.Lines
@Day(25)
class Day25(@Lines val input: IntArray) {
private val doorPublicKey = input[0]
private val cardPublicKey = input[1]
private fun encryptionKey(loopSize: Int, publicKey: Int) = transformSubjectNumber(loopSize, publicKey)
private fun transformSubjectNumber(loopSize: Int, subjectNumber: Int): Int {
var number = 1L
repeat(loopSize) {
number *= subjectNumber
number %= 20201227
}
return number.toInt()
}
private fun transformSubjectNumberStartingWith(currentNumber: Long, subjectNumber: Int): Long {
var number = currentNumber
number *= subjectNumber
number %= 20201227
return number
}
private fun findLoopSize(expectedPublicKey: Long): Int {
var computedPublicKey = 1L
var loopSize = 0
do {
computedPublicKey = transformSubjectNumberStartingWith(computedPublicKey, 7)
loopSize++
} while (computedPublicKey != expectedPublicKey)
return loopSize
}
fun part1(): Int {
val cardLoopSize = findLoopSize(cardPublicKey.toLong())
return encryptionKey(cardLoopSize, doorPublicKey)
}
}
+7
View File
@@ -0,0 +1,7 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.factory.createDay
fun main() = with(createDay<Day15>()) {
println(part1())
}
@@ -44,13 +44,6 @@ class Grid<T> {
fun edges() = listOf(row(0), column(0), row(lastRowIndex), column(lastColumnIndex))
fun neighbours(x: Int, y: Int) = listOf(
x to y - 1,
x + 1 to y,
x to y + 1,
x - 1 to y,
).mapNotNull { this[x, y] }
override fun toString() = buildString {
data.forEach { line ->
append(line.joinToString(""))
@@ -1,7 +1,5 @@
package be.vandewalleh.aoc.days.geometry
import java.util.*
private fun <T> ArrayList<T>.reversed(): ArrayList<T> {
val out = ArrayList<T>(this.size)
asReversed().forEach { out.add(it) }
+419
View File
@@ -0,0 +1,419 @@
eeneseeeneeseweeeneswneenwwee
swswswneswwseenwsenwsweswse
wswswswnweswnwswswwwswswswweswswswsew
seswswnweswswswseseseswswswswswswseswse
nwswswswswseseswseseswswswswseswswsenwsw
nwnwnwnwnenesenwneneswswwswnenenwnwnw
ewwwwwswswwwwwnwnewwwwwww
nwswneewwwsewnwswnwneswnenwnwsenweswnw
seseseseseseeswsesenweswwseswseseswse
wwnwwsewenwsww
nwnwsenwnwenwnwnwnwwwnwnwnwwnwswwnw
wwwnwwwesewwwwwwwwweww
swenwwswswswseneneneseswswnwnenwswee
eseeseseseeeswseeneweneeeseese
nwswswnwnwswsweeweseswswswseswswsesee
swswswwseswnenwneneswseseswsweseswswnw
nwnwnenwnenwnenwneswnw
eeeweneweeseneeneeeseeeeee
nenenenwneneneneneneeneneneswnenenenene
wwenwswwnwsenwwsenenenwnwsw
nwnewnwnwnwnwnwnenwsenwneewnwnwsenwwse
swwnewwsenwwswwwwswwswswse
senwswseseswswseseswseswswsewswseswsesee
swswweswnwswwswwswwswswswww
wwwwswwnwwwwwnenwewnwwwnwnww
wewwweswneswswseseswwnewwsenenw
senwsesesesesesenwswseseseeseseseseseswse
seseseswswswswseswseesesesenwse
swnwswswswsweswseswswswswswswswsw
wewwenewnwnwwewwweswnwswsww
wwsenesewwwwwnewswwwwswnwwwsw
nwsenenenewenwnwnenwnenwnwnwnwnwnwnene
wenwweswswewnenwswnwswwwsewnesw
swnwwswneswneeswsesenwseswnwseseneseseswsw
nesenwnwnenenenwnwnwnenwnwnwnwwnenenenw
eneswswneeseenenwweeeeweeeee
swneneneneeneneneweneneneneneneneneseene
nesenwsewewseswseseseseswseneswnesene
nwnewewneswwsewwwwsewsewwnew
eeweeeeeeeeeeeneeeeeswe
nwswwnwsweswnwnwseewnwnwwneewsew
neswswsewswswseswsenwswswneseesww
eenwnwwenwswswswneseseseneeweenwsw
seseswswseswnwseseswsesewswseseseseneswe
sewwnwnwswnwnwnwwwnwnwnwewnwwnww
sewswwswwnwnesewswwswnwesewswwnw
seswswseseswsenwswseswseswseswseswswesw
wseneseseswseswseswseswseseseswsesenwsese
eseeneswwswnwnwse
swswswswsenwseswswswseesesesw
wswswswwneswswswswsweswswwswnwwswswsww
nwnwnwneswneswswnwnwneswnwnenwnwseenwe
swsesewnwseseseeswswswseseseseseseswsese
senwsenwnwnwnwnwnwnwnwnwwnwnwnwnewwnwnwnw
nweeesweeseenweneesenweseswwse
sesesewseneewseseeeseeeesee
sweswswswnenwswswswnwseswsewswswwee
nwwwsewseeseneseesesewseneseenee
nwnenenenwswneneneneenenenene
seswwseseseseseseseseseswseesesesesenw
neneswnwneneenenenwneneswnwnw
seseseeeswewneneswnwswwsenwesewnee
swwseswseswwsweswswneswswswseseswsw
neneewewneneneneeewneeenenesee
seneeseseeseesenweseseseseseswseseese
nenwwwwwswswwwwnwwwwwnwewww
swswswswswswswswnewnwswswswseeswswswsesw
seseeeseswsesesesesesewsenewsesenwswse
swswswswswsweswswwswnwnwneswwsweseswsw
nwsweswnwnwnwnenenwnesenwnwnwnwwnwnwnwwse
seseseseseseseseesesenwwseeseneseesese
weneseseeseseswsweseneneneesesweswne
seseseswseswesesenwsesesesesesesesesewne
neswnwnwnwnewnewseenwnwswsenwnwnwnwsw
neswnwnewneswewseeneneneneneeeeenee
nwnwnwwnwenwwswneww
nwenwnwswwnwnwwnesenwswnwnwnwnwsenwnwenw
seseswswswswnwswswswswswnwsweswseseswswswse
neneenenwneseneneneneseneeneneneenwnene
ewwnwnwwwwwwwwwww
nwnenenwneseneneswsenewnenenwsenwnenwnene
wsesewwnenenwswnwwweewsenwnw
nwnwsesenwenwnwwwnwwsenwnewnwnenwsesw
swswwsesesewwneeswseneswwneswneswswne
enwnwswnweswswnwenwnwnwnwnwnwnwnwnweswnw
eseeswnwnesewseneeenwsesenwsewswwne
neswwseneswseweswseswswnwnese
wwwneswwswwwwswwwnewwwwwww
nenenwnenenenenwneneswenenwnenene
neneswnwneswwswnwnesenenenenenwnenwnenenw
wnenenwsenwnenwnenenwnwnenwnwnwsenenewne
wnwnwnwnwnwwnwsenwnwnwnwnwnwnwnw
eswseswswseswswsweswnenwswswswswswswnwsww
wswwseseseseswseseseseseseswseneseseese
seeseeeseseseseenwsesesesesenweseesw
eswnwseswsenwswwnenwswswswnesweswswwsw
neeseenewneneesw
nwenenewswseeneswenewswnwseswwwene
wswwenwwenwseeswnewswsewnwneseswwne
eseswseesewseseseenwesesese
nenenenenweneneswnewnenenenenenenenwne
seseneneeseswwseneseswnwneseseeenwesw
seeswseeeeswnweeeeenweeweee
seeeenweseseseesesweenweseneee
neneewnwneneseneswnesenenwenenwnenesw
nwnewnwenwnwnwswnenwnwnwnwnwnwnwsenwnwnw
ewsweswseswswswwewneswwwswesww
eneeseseeeeseseswwseeseseseeene
nwsesesewwnwnewnesenwnewwseseenew
sewswswswseseswswswseswseswswswneeswnwswe
neswneswnenenenenewnesenwnwnenwneswnenenene
nwnwnwnwnesenwwnwnwnwnenwnwswnwnwwnwnwnw
swseseseswswsewneswsenesenwenenwseseese
neswseseseswseswsesesewsesesesese
seseeeswnwseeeswseseseesenwseseee
swneswswswwswsenwswswswseswswswswseswswswsw
wsenwswwwwswswww
nwseswseesewseeswsewswnenesenwsew
nesweeseeweenenenweneswnenenee
wnwwwnwwwswnewwnwnwwewnwnwnww
wnwnenwswswnwnwsweesenenweswnewenw
seeseesenwseseseeeseseeseeseese
swseswswwswenwswswswswswswnenwswswswswse
eswseswwwnewwsewwwwwswswenesw
wnwnwswwnwnwswnwnwnenwwwwnwnwnweeww
seswwseswnesweswswseseswswseswseswswswse
nwnenwnwneneneneswneneswnwswnenenwneeneswne
swwwewswwnwwewwswwswswwswwwsw
seneenwswwseeseseneewenwseneswnewe
wwsenesesesenewewnesweseewsesw
nwwswwwesewwwwwwnwwwwwwwnww
newwnwwnenwwswsesewswseseewwnwwwsw
newswswseswswswwswswwswsww
eeesenweeeenweeesenwseeeenee
ewenenesewseswseweseeeeseeseese
eeeeeneeeeeeseeswenwnweeeee
wwnewnwenewewsewseseneweswswne
wnwwswneneneneseneseneweseenwneseneee
swewnwwnwnwneseneewneneneneene
enwnwseeneeneneeeneneeeneeswnene
sewswseneswwseeswneswseswnesenw
nenenwnenenwseneneneneseswnenenenewnene
eseseseseeeseeseseeseenwsesesenewsw
newenewnesweeeswneeeseenwnenee
wswswsenwswswsweswneneswswswswswsesesw
wsesenwsesesewsesesenesesesesenesese
eseswswseswswswswnwswswsenenwswseswswsesw
nwsewsewswswwwnwsenewnwwwwnwew
seeseeweewwsenwwneneneeswesewne
nwsweseswseseseswneeseseswnwseswsenesw
seswswswwneswsesenesewswnenwswswseswwse
seeseweseseneswnwseseseesweenwsenw
sweswseswwwswnwswnenwwsewswwnwswsw
eeeeeeeneswneneeneeswnweenwnese
nwwwnwnwwwsewnwwswnwnenwnwwwww
swswseseswswsenwswswswneseseswsewseswswsee
eseeeseseeseseewsenenwewsese
wwwwwwwwnwswwnwwewwwwnww
wneenesesenenwwnenwnwneswsenenweswne
wswnewwwwwwwwww
enenwnenenwnwnwnwnwnwwnenw
nenweswswswnenwnenwseneeswesewnenenew
neeneneswnenwneswsweeneneeneenwnenene
sesesesesesesesenwnwesesesenwwesesese
wswwswswswwnwnwwseswswwswswsew
nwneseewnwnwnenwnewnenenenwnenwnenwnenw
neeeneeeneeeneeeneenesweneenew
seswneswsenwesesesewseswseswsesewsesw
neswnenesenenwneneneswnenenenenenenenenene
neswwswswnwswswswswswsesweswswswswswsw
enwwswnwnwwnwnwnenwnwsenenwnwwnwnwnw
swnwswwswswswswesweswseseswswseseswsw
wsenenwsenwnewsenwnwnwsw
nwnwenwsewwswwnwweswnwsewsewnesew
nwnwenwnenwnwnwwnwnenwnenwnw
newneweneneneenenenwnw
swenesesenesesesesesewseneswsesesesese
swneneneneseeseeneeseeneewswwwww
nwnwnwenwnwnwnwwnwwwnwnwnenwnwswnwse
nwnenwneneswesenwswsewnenwnwnwnenwswese
seseswswswswsweseseseswnwsesw
nwenenwneneneneneenenenesweneneswnenene
nenwwwnwsenwnwnwnwnwsenwnwnwnwnenwnwnwnese
neneeeeweneeneneswnwnenenwneneswne
wwwneswnwnwnwwnwnwewnwnwwwwsenew
eenweeeeeesweeeeeee
eneweseseeeswewsewseswsenwesenw
nenenwnenenenwseswsewnenenwneswnw
nwwwswnwswnwnenwwenwnwnwnenwswnwnwnw
eswseneeeewenweeseswsewseenee
wswswnwneseswseseneswsww
sewwwwwnwwwwwnenwwwwwnwwnw
enwnwnwwwnwwsenwsewnwwsewswwnwwnw
swseswenwenewnesweseswnewsenwseswwwsw
nwswwnwnwnwnwenwnwwnwnwwwnwnwnwnww
wenwswnenenenenenwne
swwwnwnwwwwnwewwwwnwnwenwnwnw
nwswneswneswsenenesenenwnwwnenwnwneene
neneswneweneneeeweneneeeenenwene
neenweneswnwneneneneneneneneswnenenwnenene
wswnwwwwnwwnwweeswnwwnwwwew
eweneeswneneneeeeeeeeeeew
seeneeseseseswswsenwnwseneeesweee
eneeneseenesenenenenenenwwwneeneswse
swseneenenenenenenesenesenewwnwnenene
swnenweeeeeneeewswenwenwswewsene
eswnwnwwnwnwswseewnesenwwnweseww
nwnewseewnwwwwnwnwswnwnwnwnwnwwnw
nwnwneenenesenwnenenenenenenwnenwswnew
swwswnewewwwwwwwwewwnwwwsw
eeseseseeeeeseenweeeeswe
nwnwnwweswnwenwnwnwnwnwnwnenwnwnewnw
swwsweneswsewnwwswswwsweenwsww
neswneneswseswenenenenenenwnwnwnesw
wwwnwswwwswneewwwnwnwewwwe
enesewnwwsesenenewwwwsw
neneneswnenenenenenesenenenenenenwswnwne
seswseseswsesweseseswswnwseseswswsesesw
nwnwnwnwsewwnwwnwwnwwnenwnwnwnwnw
seeeeeenewneeswneeeenesenwnene
wwewwwwwwwwwwwwnwsewnw
seseswseseseneesesewsenese
sesweseswsesesewwseweeseseseenwsw
neswseswswwswswseswswswswswwwneswwsw
ewseneseeneswseeesesw
swswwnewnwswneswnwwnewsesewswswswwe
nwnwnwnwnwnenwnwnwnwnwnesenwnw
swnwewsenwwwwwswsewnwneenwnwwnww
swswswseseswseseswnwsewswsesesesenesw
neenenwneneneneneeeeeneeeneeswese
eneeeneneeneeswswnee
swnewswwwswswswswswswswswnwseswsenewswsw
swseswsesweswsewswswseswseseneswswswsww
swenwnenewswnewwsewnwenwnwswnwswwnew
swswwwsenwwnwswsewnesewwnwnenene
weneneeneswnweeweeswweeswnesw
nwswsenenwesenwnwsenwsewenwswnwnwnwnew
nesweenwneeeswwneneneeneeneenwenee
nesesweswswwswswseswswseseswswseseswsw
eeewswnweesweeeseenenenenewee
sewwsesesesenenwseneseseseseseesewsesw
nenewsewnwnwnwneneswnenenenesenwenw
sewwwwswwsewwwwnwnwwwwwwwsw
sesewwseseseseseseseseneeseseeeseese
neneneewwnenenenenenwneneseeesenene
eseeeneneenweeeeeneeee
enwswnwwswenwneewswnwswwseseswseenew
nwnwnwnenwnwnwwnwnwnwnwnwwnwnwnwsenwnw
seswswswenwnwswswswseenewswneneswwsw
wswswwwewwnwswswswnwwesewwsww
seseseeseseseseseeseswseswnesesenwsesese
swnenwswsewwsewswnwswswswnwneenesee
nwnwwsenenwnenwnwnwnwwnwnwswnwnwnwnwnw
senwwswnewwsenewwwsewewwwwwww
wnwwwwnwsenenewwnwwewwnwwnwsenw
ewseewsewnwnenewwwwswwneewww
wnesenweenenweeswwenwesenesenee
eweneneneneweeeeeneswneneseesw
nwwsenewwnenwenwswewwwwseswwww
eewseseeeseeseeseneeseeeeese
wswwneswnwwnweenwnewwswnwnwwwnwwsw
nwswsenwwwnwwwwswnwwnwwnwenwwnenw
wsweswwswswwwwsewweswnwwwswww
neeeweenwneneeneeeseeeneeeeesw
swswswseswwswneesewswnwswseseseswsw
swwwwwnewwwwwwwwww
ewwwewwwwswneswwwwwnwwwwww
swwswswswwsesweswswswwwswseswswnewnw
nenwnwnenwnwnwnwnwnwnwnwnwnwswnenwnesenew
swswswswweswswswseswswswswswswwswnwsw
eeseeseeeeseseseseseeseeesenwnw
seseeseseseseneseseseseseseseseswsewnew
nwwnwnwswswenwnwnwsenwwswnwnwnwewnwnee
eeneswswneeeeeeeeeeeeenene
swswswnwswwswswswneswswswswneseswswswswsw
nenwnwnenwnwneswnwnwnenwnwnenene
swnwnwnenewenenwnenwsenenwnwnw
swswswswswnwwswswswswswnewwswsweswsw
swswsweswneswswswswwwswseswswswswwsww
neswnwswsenewnesenwenenenewnwnwnw
eeeeweewneeeeeeeeeeee
sewswswseseweeseseseeseswnenwenwsene
swswsenwswswswswswswseswswswnweswnwesw
wnesenweeneneneenesenewneeneneene
nwnwnwnwnwnwwnwnenese
wweeeneeeeeseseee
nwnenenwnwwnwnenenwnwnwnwesenenwneseswnw
eeeswenweseeeeeseeenewnwswe
enwneeweneeseswsenwnenwseneneneesw
seseseseseswsesewsewseneneseneneswsesw
seseseeseesenwseseesenwsweeesewse
neeeeeneswweewneeeseeeeenee
swswswwswswswswseswswneswswswwsweswswsw
swswswseswseswswswswswnewseseseswswswse
swwwwswswswswnweswswwswne
wwwnwnwwwwwnewwnwwnwnwnwnwsew
swswswswswswwwswseswnwneswseswnesw
nwneseswsenewnweneswsenenenenwnenene
seseeseseeseenweeseseeswswesesesenwe
neeneneweenewneneenwnweneseesweee
eneeseeseeswsweneeseseseesee
swnenwnwsenwseswsenwseenwswwsesenwsese
eseseeeeswseeeeenweeeeeee
eneeneeneeeeswesweeeeneeene
nwnwewwnwnenewsesenwnwnwnwseesewnww
swswswswswswseswswnwwswnewswseneswseswsw
nwnwnwnwnwnwnwnwwnwnwenwnwnwnwnwnwnw
sewswswswseneesesenweswnwswsesenwseesw
eneeeseesenwweseeneeweeew
nenenenenenenenwneneneneneneenewswe
wwwswwneswwnwenwwnewswnewsesww
wsewwswwnwwwewwnwnwwweswwse
nwesenwnwnwnwwsewenwnenesweneswwnwe
swneswnesweswnwwnenenweeew
nwnwwnwnwenwnenenwnenwenenewneswsenwnene
nwnwnenwsenwwnwwnwnwenwwnwnwwnw
neseseneswwswwseswswsweswseswseseseswsw
nenenenewsenwseenenewneswsenenewnenenene
seseseesesesesesesenwswsewseesesesesese
eneenenenewseseeeneenenwnenenenenenene
nwswnwswneswwseeswswswseswswswswswsww
swweswsewswwseseseswswswswseswswee
nwnenwenewwwnwnwnenenwenwnwesenwne
wwwwwswswewwswwwwwswsweswww
swswwnweseenwwnwwwswswwwseseswnwe
nwnwwnwwwnwenwswwwnewseswnwnwsene
wwwswwwwwswwseswswswnwneseswwsw
wwnwnwwwnwnwswenwnwnwnww
neneeeneswnewneeenenwswee
newnwnenenenwneneswsenenenenenewsesenenene
eseseeseseswwnwswsesenwwsenenwseseene
neneswnenenenwnenwnwne
wswwseswnenwwwswwwwwwwwswneww
seewwewwneeewesenwwnenwwnesesw
neneneneneneeneswnwnenwneneneneswwnwne
nwnwnenenwnenwnewnwsenenenenenenwneneenw
nwwnwnwenwnwnwnenwsenwnwnwnwnenwwnwnwe
swsewwnenenwneneneeneneswneenenenenwswne
eeneneeenesesweewsweenenenwnwenee
nenenwneneswseneneneeneeneneneenenene
wswwwseenenwsenwnesesenwneswnwnwwe
wseswswswwwswswswnwewswswswswswswswsw
nwswseswneneneeneswnenwswneneneneenenwe
sewnenenenenwseswnesenenwsenwnwnenenene
nwwwnwswwneeeewnwnwswewnwnwsenwe
seseseeeesewneseesese
nesenenenenenenenenewneneneseswnenenenew
nwswswswswwswswswwswswswswswswseswswswne
wwwwwsewwwnewwwwwwwwww
nenwnwnwnwneenwnwwnwswnenwswsenesewse
eeseseswseseeeeeeeeseseenesesenw
nwnenenwnwnwnwnwsenenwswnenwnenenwnenenwne
nwwenwnwnwnwnwnenwnenwnwnwnwnwnweswsw
nenwsenenenenenenenwnewnwenwnenenwne
nwwnwwnwseneeseseswnwneeeseeneenee
wewnwnewwnwwwwswwwnwwwseswww
neswseeseseseseseseswsewnwseswswswswsee
sewsesesesenwsenwenwwnesesenwnwse
seeeeneneeeneeeeewwneeeene
neneewwneeneeeeeneneeeeneeee
nwsesweswesesesesewswseseswswseswseseswse
wwnwnwwnwnwnwnwnwwwnenwwnwnwsenww
wnwsewnesweewsenwwenwnwenwwwse
wswwwewswwwwwwwswnweww
swswnwswswswswswnweneswnewneseseswswswne
weseseenwweeswenwseeenesewsenw
swswswswseneswswswswswswswneswswswwswswsw
senenenenwenesenewseenewswneneeene
swnwswseseseseesesewswseseseseseswnwe
neswswewwwewnwwwnwswwnwneewwwsw
swwnewnwweswswnesenwswewseswswseswsww
eseseweeneweeeeeeeenewsew
eeseenwsenwswseeesesesenwwsesenwsew
esweswwseesenenesesenwsesesenwseseee
senwswnwswnwnwswseswswswseseesw
nenwneneenenenewnenwnenenenenenenenesene
seeseeenenwewweesenwweneneeswe
wwwnewwwwwwwswwwwwwsw
neseswsenwseseseseseseswseseseswseseesw
neneeewsewsewenesewnesewsewsew
wwswwnwnwenwnwwnwwwenwwnwnwnenwse
nwnwswnwnenwwnwnwswneswenwwwswnwwe
enenwwneeeeeeeneneeeeeeeeswe
weeeeswesenwse
nwnwnewnwsenenenwnwnwsenwnwnwnwnewnwnwenw
swenesenewwwenenwsewswwwsewnwe
nwswwnwwnenwnewwsenewwwsewwnwse
nwnwnwwnwnwwnwsenwnwwwnewnwnwwwnwnese
seswswwwwwwswswswswswwnewwwww
neswwseenwwnwswseneeewswnwseneesww
seesweswenweseenwnwseswwnesenwwnwee
seseseseneswseseseseseswseseswenenwsese
seesenesesesenwwseseseseneseseseeww
eseseeseseeeseseseseeseseewsesene
wsewwwwwwnenwnwwwwwwnewwnwsw
eseswesenwseseeseeeeseseseeesee
neneneseeneneenewneneneneneene
neeseseseseeseseswseeee
seeeesesesweeesewseneseeesesee
enwweeeeeeeeeseeeeeeesee
wwwseswsewnewwnenewswswswswswwsww
seeewnweseswenenenweeeenee
nwsenwwwwnwnwswnwwwne
wesesewswswneeenwnweneenweneseesw
eeswswwnwswnwnwnwnwesenwwnwnwwnenwnw
nweenwseseneeenwseneenwneswneenee
nwsenwsenwnwnwnwnwwwnwnwnwnwnwnewnwne
seesewseeseseneseseseswsesesesenesese
swwseswnwwwswwswwswwew
enwneenenenewnewsenenenenenenesenene
swwswswwwwwwswneswwswwseswwsene
neenenenwnesweneewswne
nwnwwnesenwnwnwnwnenenenenenwnwnwnenwne
neeenesewwnwsenwswseseeseneswsewsesw
newwnwswswnewswwswwswswwwsewww
wsewwneenwwww
wswwnewwwwwwwwww
wwwwswwwswwnwswewwwswswwww
swseswswswswseseseswseeswswsenwsesw
+2
View File
@@ -0,0 +1,2 @@
1327981
2822615
@@ -0,0 +1,6 @@
org.slf4j.simpleLogger.logFile=System.out
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
org.slf4j.simpleLogger.defaultLogLevel=info
org.slf4j.simpleLogger.log.io.micronaut=info
org.slf4j.simpleLogger.log.io.micronaut.context.lifecycle=info
@@ -1,13 +1,12 @@
package be.vandewalleh.aoc.days
import io.micronaut.context.BeanContext
import io.micronaut.context.getBean
import be.vandewalleh.aoc.utils.factory.createDay
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
class Day01Test {
private val day = BeanContext.run().getBean<Day01>()
private val day = createDay<Day01>()
@Test
fun `part1 result`() {
@@ -1,8 +1,8 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.createDay
import be.vandewalleh.aoc.utils.factory.createDay
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
@@ -22,7 +22,7 @@ class Day03Test {
"#.##...#...",
"#...##....#",
".#..#...#.#",
).let { Input(it) }
)
private val day03 = Day03(example)
@@ -43,11 +43,13 @@ class Day03Test {
private val day03 = createDay<Day03>()
@Test
@Disabled
fun `part1 result`() {
assertThat(day03.part1()).isEqualTo(294)
}
@Test
@Disabled
fun `part2 result`() {
assertThat(day03.part2()).isEqualTo(5774564250)
}
@@ -1,7 +1,6 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Input
import be.vandewalleh.aoc.utils.input.createDay
import be.vandewalleh.aoc.utils.factory.createDay
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Nested
@@ -26,7 +25,6 @@ class Day04Test {
hcl:#cfa07d eyr:2025 pid:166559648
iyr:2011 ecl:brn hgt:59in
""".trimIndent()
.let { Input(it) }
private val day04 = Day04(example)
@@ -63,7 +61,7 @@ class Day04Test {
hgt:59cm ecl:zzz
eyr:2038 hcl:74454a iyr:2023
pid:3556412378 byr:2007
""".trimIndent().let { Input(it) }
""".trimIndent()
assertThat(Day04(input).part2()).isEqualTo(0)
}
@@ -83,7 +81,7 @@ class Day04Test {
eyr:2022
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
""".trimIndent().let { Input(it) }
""".trimIndent()
assertThat(Day04(input).part2()).isEqualTo(4)
}
@@ -1,6 +1,6 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.createDay
import be.vandewalleh.aoc.utils.factory.createDay
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
@@ -1,6 +1,5 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Input
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
@@ -20,7 +19,7 @@ class Day13Test {
)
@ParameterizedTest
fun examples(buses: String, answer: Long) {
val input = Input(listOf("", buses))
val input = listOf("", buses)
assertThat(Day13(input).part2()).isEqualTo(answer)
}
@@ -1,6 +1,6 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.createDay
import be.vandewalleh.aoc.utils.factory.createDay
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
@@ -1,6 +1,6 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.createDay
import be.vandewalleh.aoc.utils.factory.createDay
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
@@ -1,6 +1,5 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.input.Input
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
@@ -17,7 +16,7 @@ class Day18Test {
])
@ParameterizedTest
fun examplesPart2(input: String, output: Long) {
val day18 = Day18(Input(listOf(input)))
val day18 = Day18(listOf(input))
assertThat(day18.part2()).isEqualTo(output)
}
}
+7
View File
@@ -0,0 +1,7 @@
plugins {
id("aoc")
}
application {
mainClass.set("be.vandewalleh.aoc.days.MainKt")
}
+1
View File
@@ -0,0 +1 @@
target area: x=20..30, y=-10..-5
+1
View File
@@ -0,0 +1 @@
target area: x=139..187, y=-148..-89
+42
View File
@@ -0,0 +1,42 @@
import nre, strutils
let
regex = re"x=(-?\d+)..(-?\d+), y=(-?\d+)..(-?\d+)"
data = readFile("input.txt")
captures = data.find(regex).get.captures
x1 = captures[0].parseInt()
x2 = captures[1].parseInt()
y1 = captures[2].parseInt()
y2 = captures[3].parseInt()
minX = min(x1, x2)
maxX = max(x1, x2)
minY = min(y1, y2)
maxY = max(y1, y2)
proc land(dx: int, dy: int): int =
var dx = dx
var dy = dy
var x = 0
var y = 0
var high = y
while x < maxX and y > minY:
x += dx
y += dy
if dx > 0: dx -= 1
elif dx < 0: dx += 1
dy -= 1
high = max(high, y)
if x in minX..maxX and y in minY..maxY:
return high
return -1
var high = 0
var match = 0
for x in -1000..1000:
for y in -1000..1000:
let res = land(x, y)
if res != -1: match += 1
high = max(res, high)
echo(high)
echo(match)
+29
View File
@@ -0,0 +1,29 @@
package be.vandewalleh.aoc.days
class Counter<K> : Iterable<Map.Entry<K, Long>> {
private val map = HashMap<K, Long>()
operator fun get(key: K) = map[key] ?: 0L
operator fun set(key: K, count: Long) {
map[key] = count
}
operator fun set(key: K, count: Int) {
if (count == 0)
map.remove(key)
else
map[key] = count.toLong()
}
fun toMap() = map.toMap(HashMap())
override fun toString() = map.toString()
fun minValue() = map.minOf { it.value }
fun maxValue() = map.maxOf { it.value }
override fun iterator() = toMap().iterator()
companion object
}
operator fun <T> Counter.Companion.invoke(items: Iterable<T>) = Counter<T>().apply { items.forEach { this[it] += 1 } }
+27
View File
@@ -0,0 +1,27 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day01 : BaseDay() {
private val items by lazy { input.lines.ints }
override fun part1(): Int {
var count = 0
for (i in 0 until items.size - 1) {
if (items[i] < items[i + 1]) count++
}
return count
}
override fun part2(): Int {
var count = 0
for (i in 0 until items.size - 3) {
val a = items.drop(i).take(3).sum()
val b = items.drop(i + 1).take(3).sum()
if (b > a) count++
}
return count
}
}
+40
View File
@@ -0,0 +1,40 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day02 : BaseDay() {
private val lines by lazy { input.lines.value.map { it.split(' ').let { it[0] to it[1].toInt() } } }
override fun part1(): Int {
var horizontalPosition = 0
var depth = 0
lines.forEach { (direction, value) ->
when (direction) {
"forward" -> horizontalPosition += value
"down" -> depth += value
"up" -> depth -= value
}
}
return horizontalPosition * depth
}
override fun part2(): Any {
var horizontalPosition = 0
var depth = 0
var aim = 0
lines.forEach { (direction, value) ->
when (direction) {
"forward" -> {
horizontalPosition += value
depth += aim * value
}
"down" -> aim += value
"up" -> aim -= value
}
}
return horizontalPosition * depth
}
}
+36
View File
@@ -0,0 +1,36 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day03 : BaseDay() {
override fun part1(): Int {
val moreOnes = input.lines.value[0].indices
.map { i -> input.lines.value.map { it[i] } }
.map { it.count { it == '1' } >= it.size / 2 }
val gamma = moreOnes.joinToString("") { if (it) "1" else "0" }.toInt(radix = 2)
val epsilon = moreOnes.joinToString("") { if (!it) "1" else "0" }.toInt(radix = 2)
return gamma * epsilon
}
override fun part2(): Any {
val o2 = findNumber(input.lines.value) { ones, zeros -> if (ones >= zeros) '1' else '0' }
val co2 = findNumber(input.lines.value) { ones, zeros -> if (zeros <= ones) '0' else '1' }
return o2 * co2
}
private fun findNumber(input: List<String>, keep: (Int, Int) -> Char): Int {
var numbers = input
for (i in this.input.lines.value[0].indices) {
if (numbers.size == 1) break
val eachCount = numbers.map { it[i] }.groupingBy { it }.eachCount()
val ones = eachCount['1'] ?: 0
val zeros = eachCount['0'] ?: 0
val maj = keep(ones, zeros)
numbers = numbers.filter { it[i] == maj }
}
return numbers[0].toInt(2)
}
}
+33
View File
@@ -0,0 +1,33 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day04 : BaseDay() {
private val numbers by lazy { input.lines.value[0].split(',').map { it.toInt() } }
private val boards by lazy {
input.text.split("\n\n")
.drop(1)
.map { it.lines().map { it.trim().split("\\s+".toRegex()).map { it.toInt() } } }
}
private val results by lazy { boards.map { playBoard(it) } }
override fun part1() = results.minByOrNull { it.first }!!.second
override fun part2() = results.maxByOrNull { it.first }!!.second
private fun playBoard(board: List<List<Int>>): Pair<Int, Int> {
for (round in numbers.indices) {
val usedNumbers = numbers.take(round)
for (line in board + board[0].indices.map { col -> board.map { it[col] } }) {
if (usedNumbers.containsAll(line)) {
val unmarkedNumbers = board.flatten().toMutableSet().also { it.removeAll(usedNumbers) }
return round to unmarkedNumbers.sum() * usedNumbers.last()
}
}
}
error("No wins")
}
}
+50
View File
@@ -0,0 +1,50 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day05 : BaseDay() {
data class Point(val x: Int, val y: Int)
private val re = "(\\d+),(\\d+) -> (\\d+),(\\d+)".toRegex()
private fun path(start: Point, end: Point): Sequence<Point> {
val dx = end.x.compareTo(start.x)
val dy = end.y.compareTo(start.y)
return generateSequence(start) {
if (it == end) null
else Point(it.x + dx, it.y + dy)
}
}
override fun part1(): Int {
val visited = HashMap<Point, Int>()
input.lines.value
.map {
re.find(it)!!.destructured.let { (x1, y1, x2, y2) ->
Point(x1.toInt(), y1.toInt()) to Point(x2.toInt(), y2.toInt())
}
}
.filter { (start, end) -> start.x == end.x || start.y == end.y }
.flatMap { (start, end) -> path(start, end) }
.forEach { visited.compute(it) { _, value -> (value ?: 0) + 1 } }
return visited.values.count { it >= 2 }
}
override fun part2(): Int {
val visited = HashMap<Point, Int>()
input.lines.value
.map {
re.find(it)!!.destructured.let { (x1, y1, x2, y2) ->
Point(x1.toInt(), y1.toInt()) to Point(x2.toInt(), y2.toInt())
}
}
.flatMap { (start, end) -> path(start, end) }
.forEach { visited.compute(it) { _, value -> (value ?: 0) + 1 } }
return visited.values.count { it >= 2 }
}
}
+27
View File
@@ -0,0 +1,27 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day06 : BaseDay() {
override fun part1() = run(80)
override fun part2() = run(256)
private fun run(days: Int): Long {
var fish = LongArray(9)
input.csv.ints.forEach { fish[it] = fish[it] + 1 }
var newFish: LongArray
for (day in 1..days) {
newFish = LongArray(9)
for (timer in 8 downTo 1) {
newFish[timer - 1] = fish[timer]
}
newFish[8] = fish[0]
newFish[6] = fish[0] + newFish[6]
fish = newFish
}
return fish.sum()
}
}
+28
View File
@@ -0,0 +1,28 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
import kotlin.math.abs
@Day
class Day07 : BaseDay() {
override fun part1(): Any {
val ints = input.csv.ints
return (ints.minOrNull()!!..ints.maxOrNull()!!).minOf { target -> ints.sumOf { abs(it - target) } }
}
private fun calc(position: Int, target: Int): Int {
val diff = abs(position - target)
var sum = 0
for (i in 1..diff) {
sum += diff - i + 1
}
return sum
}
override fun part2(): Any {
val ints = input.csv.ints
return (ints.minOrNull()!!..ints.maxOrNull()!!).minOf { target -> ints.sumOf { calc(it, target) } }
}
}
+49
View File
@@ -0,0 +1,49 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day08 : BaseDay() {
override fun part1() = input.lines.value
.map { it.split(" | ")[1].split(" ") }
.sumOf { it.count { it.length in setOf(2, 3, 4, 7) } }
override fun part2() = input.lines.value
.map { it.split(" | ").map { it.split(" ") } }
.sumOf { (pattern, digits) ->
val patterns = decodePatterns(pattern)
digits.map { patterns[it.sortChars()] }.joinToString("").toInt()
}
private fun decodePatterns(patterns: List<String>): Map<String, Int> {
val result = Array(10) { "" }
result[1] = patterns.single { it.length == 2 }
result[7] = patterns.single { it.length == 3 }
result[4] = patterns.single { it.length == 4 }
result[8] = patterns.single { it.length == 7 }
val frequency = patterns.flatMap { it.toCharArray().toList() }.groupBy { it }.mapValues { it.value.size }
val a = (result.letters(7) - result.letters(1)).first()
val b = frequency.findKey { it.value == 6 }
val c = frequency.findKey { it.value == 8 && it.key != a }
val d = frequency.findKey { it.value == 7 && it.key in result.letters(4) }
val e = frequency.findKey { it.value == 4 }
val f = frequency.findKey { it.value == 9 }
result[0] = patterns.find { it.length == 6 && d !in it }!!
result[2] = patterns.find { it.length == 5 && b !in it && f !in it }!!
result[3] = patterns.find { it.length == 5 && b !in it && e !in it }!!
result[5] = patterns.find { it.length == 5 && c !in it && e !in it }!!
result[6] = patterns.find { it.length == 6 && c !in it }!!
result[9] = patterns.find { it.length == 6 && e !in it }!!
return result.mapIndexed { index, value -> value.sortChars() to index }.toMap()
}
private fun Array<String>.letters(number: Int) = this[number].toCharArray().toSet()
private fun <K, V> Map<K, V>.findKey(predicate: (Map.Entry<K, V>) -> Boolean) = entries.find(predicate)!!.key
private fun String.sortChars() = toCharArray().sorted().joinToString("")
}
+36
View File
@@ -0,0 +1,36 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
private data class Point(val x: Int, val y: Int)
private fun Point.adjacents() = listOf(copy(y = y - 1), copy(x = x + 1), copy(y = y + 1), copy(x = x - 1))
@Day
class Day09 : BaseDay() {
private val map by lazy {
input.lines.value.flatMapIndexed { y, line ->
line.mapIndexed { x, value -> Point(x, y) to value.digitToInt() }
}.filterNot { it.second == 9 }.toMap()
}
private val lows by lazy {
map.keys.filter { point -> point.adjacents().mapNotNull { map[it] }.all { it > map[point]!! } }
}
override fun part1() = lows.sumOf { map[it]!! + 1 }
override fun part2() = lows.map { low ->
val visited = HashSet<Point>().apply { add(low) }
generateSequence(hashSetOf(low)) {
it.asSequence()
.flatMap { it.adjacents() }
.filter { it in map }
.filterNot { it in visited }
.toHashSet()
.also { visited.addAll(it) }
.ifEmpty { null }
}.flatten().count()
}.sorted().takeLast(3).fold(1) { a, b -> a * b }
}
+56
View File
@@ -0,0 +1,56 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day10 : BaseDay() {
private val chunks = mapOf(
')' to '(',
']' to '[',
'>' to '<',
'}' to '{',
)
override fun part1(): Any {
val points = mapOf(
')' to 3,
']' to 57,
'}' to 1197,
'>' to 25137,
)
return input.lines.value.sumOf { line ->
val stack = mutableListOf<Char>()
for (char in line) {
if (char in chunks) {
if (stack.last() == chunks[char]!!) stack.removeLast()
else return@sumOf points[char]!!
} else {
stack.add(char)
}
}
0
}
}
override fun part2(): Any {
val points = mapOf(
'(' to 1,
'[' to 2,
'{' to 3,
'<' to 4,
)
return input.lines.value.mapNotNull { line ->
val stack = mutableListOf<Char>()
for (char in line) {
if (char in chunks) {
if (stack.last() == chunks[char]!!) stack.removeLast()
else return@mapNotNull null
} else {
stack.add(char)
}
}
stack.foldRight(0L) { char, score -> score * 5 + points[char]!! }
}.sorted().let { it[it.size / 2] }
}
}
+63
View File
@@ -0,0 +1,63 @@
package be.vandewalleh.aoc.days
import be.vandewalleh.aoc.utils.BaseDay
import be.vandewalleh.aoc.utils.input.Day
@Day
class Day11 : BaseDay() {
private data class Point(val x: Int, val y: Int) {
fun adjacents() = listOf(
copy(y = y - 1),
copy(x = x + 1),
copy(y = y + 1),
copy(x = x - 1),
copy(y = y - 1, x = x - 1),
copy(x = x + 1, y = y + 1),
copy(y = y + 1, x = x - 1),
copy(x = x + 1, y = y - 1),
)
}
private val map by lazy {
input.lines.value.flatMapIndexed { y, line ->
line.mapIndexed { x, value -> Point(x, y) to value.digitToInt() }
}.toMap()
}
override fun part1(): Int {
val map = map.toMap(HashMap())
var count = 0
repeat(100) { count += step(map) }
return count
}
private fun step(map: HashMap<Point, Int>): Int {
map.keys.forEach { map[it] = map[it]!! + 1 }
val flashed = hashSetOf<Point>()
while (true) {
val count = map.entries.asSequence()
.filter { it.value > 9 }
.filter { it.key !in flashed }
.onEach { flashed += it.key }
.flatMap { it.key.adjacents() }
.filter { it in map }
.onEach { map[it] = map[it]!! + 1 }
.count()
if (count == 0) break
}
map.entries.filter { it.value > 9 }
.map { it.key }
.forEach { map[it] = 0 }
return flashed.size
}
override fun part2(): Int {
val map = map.toMap(HashMap())
repeat(10000) { if (step(map) == map.size) return it + 1 }
return -1
}
}

Some files were not shown because too many files have changed in this diff Show More