diff --git a/src/main/java/net/bqc/aoc/DayGenerator.java b/src/main/java/net/bqc/aoc/DayGenerator.java index c8af115..4026bb0 100644 --- a/src/main/java/net/bqc/aoc/DayGenerator.java +++ b/src/main/java/net/bqc/aoc/DayGenerator.java @@ -4,9 +4,7 @@ import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; -import org.jsoup.select.Elements; -import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; diff --git a/src/main/java/net/bqc/aoc/utils/SolutionUtils.java b/src/main/java/net/bqc/aoc/utils/Array2DUtils.java similarity index 58% rename from src/main/java/net/bqc/aoc/utils/SolutionUtils.java rename to src/main/java/net/bqc/aoc/utils/Array2DUtils.java index d081719..75ffdc5 100644 --- a/src/main/java/net/bqc/aoc/utils/SolutionUtils.java +++ b/src/main/java/net/bqc/aoc/utils/Array2DUtils.java @@ -1,16 +1,11 @@ package net.bqc.aoc.utils; -import java.math.BigDecimal; -import java.math.MathContext; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -public class SolutionUtils { +public class Array2DUtils { public static char[][] readAsMatrix(List inputLines) { int m = inputLines.size(); @@ -69,33 +64,6 @@ public static List getXPos(char[][] matrix, char x) { return posList; } - public static BigDecimal[] solveQuadraticEquation(BigDecimal a, BigDecimal b, BigDecimal c) { - BigDecimal discriminant = b.pow(2).subtract(new BigDecimal("4").multiply(a).multiply(c)); - - if (discriminant.compareTo(BigDecimal.ZERO) < 0) { - return new BigDecimal[]{}; - } - - BigDecimal sqrtDiscriminant = discriminant.sqrt(MathContext.DECIMAL128); - - BigDecimal x1 = b.negate().subtract(sqrtDiscriminant).divide(a.multiply(new BigDecimal("2")), MathContext.DECIMAL128); - BigDecimal x2 = b.negate().add(sqrtDiscriminant).divide(a.multiply(new BigDecimal("2")), MathContext.DECIMAL128); - return new BigDecimal[]{x1, x2}; - } - - public static long gcd(long number1, long number2) { - while (number2 != 0) { - long temp = number2; - number2 = number1 % number2; - number1 = temp; - } - return Math.abs(number1); - } - - public static long lcm(List numbers) { - return numbers.stream().reduce(1L, (a, b) -> a * b / SolutionUtils.gcd(a, b)); - } - public static boolean isConsecutiveArray(long[] arr) { for (int i = 0; i < arr.length - 1; i++) { if (arr[i] + 1 != arr[i+1]) { @@ -140,41 +108,6 @@ public static int countInMatrix(char[][] matrix, char toCount) { return count; } - private static final MessageDigest digest; - - static { - try { - digest = MessageDigest.getInstance("SHA-256"); - } - catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } - - public static String generateSHA256(int[][] matrix) { - StringBuilder res = new StringBuilder(); - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[i].length; j++) { - res.append(matrix[i][j] + '0'); - } - } - - byte[] encodedHash = digest.digest(res.toString().getBytes(StandardCharsets.UTF_8)); - return bytesToHex(encodedHash); - } - - public static String bytesToHex(byte[] hash) { - StringBuilder hexString = new StringBuilder(2 * hash.length); - for (int i = 0; i < hash.length; i++) { - String hex = Integer.toHexString(0xff & hash[i]); - if(hex.length() == 1) { - hexString.append('0'); - } - hexString.append(hex); - } - return hexString.toString(); - } - public static void swapElements(int[][] matrix, int row1, int col1, int row2, int col2) { int temp = matrix[row1][col1]; matrix[row1][col1] = matrix[row2][col2]; diff --git a/src/main/java/net/bqc/aoc/utils/EncryptionUtils.java b/src/main/java/net/bqc/aoc/utils/EncryptionUtils.java new file mode 100644 index 0000000..9a5ea73 --- /dev/null +++ b/src/main/java/net/bqc/aoc/utils/EncryptionUtils.java @@ -0,0 +1,42 @@ +package net.bqc.aoc.utils; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class EncryptionUtils { + private static final MessageDigest digest; + + static { + try { + digest = MessageDigest.getInstance("SHA-256"); + } + catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + public static String generateSHA256(int[][] matrix) { + StringBuilder res = new StringBuilder(); + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[i].length; j++) { + res.append(matrix[i][j] + '0'); + } + } + + byte[] encodedHash = digest.digest(res.toString().getBytes(StandardCharsets.UTF_8)); + return bytesToHex(encodedHash); + } + + public static String bytesToHex(byte[] hash) { + StringBuilder hexString = new StringBuilder(2 * hash.length); + for (int i = 0; i < hash.length; i++) { + String hex = Integer.toHexString(0xff & hash[i]); + if(hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } +} diff --git a/src/main/java/net/bqc/aoc/utils/MathUtils.java b/src/main/java/net/bqc/aoc/utils/MathUtils.java new file mode 100644 index 0000000..394449b --- /dev/null +++ b/src/main/java/net/bqc/aoc/utils/MathUtils.java @@ -0,0 +1,34 @@ +package net.bqc.aoc.utils; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.List; + +public class MathUtils { + public static BigDecimal[] solveQuadraticEquation(BigDecimal a, BigDecimal b, BigDecimal c) { + BigDecimal discriminant = b.pow(2).subtract(new BigDecimal("4").multiply(a).multiply(c)); + + if (discriminant.compareTo(BigDecimal.ZERO) < 0) { + return new BigDecimal[]{}; + } + + BigDecimal sqrtDiscriminant = discriminant.sqrt(MathContext.DECIMAL128); + + BigDecimal x1 = b.negate().subtract(sqrtDiscriminant).divide(a.multiply(new BigDecimal("2")), MathContext.DECIMAL128); + BigDecimal x2 = b.negate().add(sqrtDiscriminant).divide(a.multiply(new BigDecimal("2")), MathContext.DECIMAL128); + return new BigDecimal[]{x1, x2}; + } + + public static long gcd(long number1, long number2) { + while (number2 != 0) { + long temp = number2; + number2 = number1 % number2; + number1 = temp; + } + return Math.abs(number1); + } + + public static long lcm(List numbers) { + return numbers.stream().reduce(1L, (a, b) -> a * b / gcd(a, b)); + } +} diff --git a/src/main/java/net/bqc/aoc/year2023/Day03.java b/src/main/java/net/bqc/aoc/year2023/Day03.java index 8df6539..2a76700 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day03.java +++ b/src/main/java/net/bqc/aoc/year2023/Day03.java @@ -1,7 +1,7 @@ package net.bqc.aoc.year2023; import net.bqc.aoc.Solution; -import net.bqc.aoc.utils.SolutionUtils; +import net.bqc.aoc.utils.Array2DUtils; import java.util.ArrayList; import java.util.List; @@ -15,7 +15,7 @@ public long solve(PART_NUMBER part, List inputLines) { int m = inputLines.size(); int n = inputLines.get(0).length(); - char[][] matrix = SolutionUtils.readAsMatrix(inputLines); + char[][] matrix = Array2DUtils.readAsMatrix(inputLines); long sum = 0; for (int row = 0; row < m; row++) { diff --git a/src/main/java/net/bqc/aoc/year2023/Day06.java b/src/main/java/net/bqc/aoc/year2023/Day06.java index f561b97..3ac5047 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day06.java +++ b/src/main/java/net/bqc/aoc/year2023/Day06.java @@ -1,7 +1,7 @@ package net.bqc.aoc.year2023; import net.bqc.aoc.Solution; -import net.bqc.aoc.utils.SolutionUtils; +import net.bqc.aoc.utils.MathUtils; import java.math.BigDecimal; import java.math.BigInteger; @@ -34,7 +34,7 @@ public BigInteger solve2(PART_NUMBER part, List inputLines) { } public BigInteger countStrategies(BigDecimal time, BigDecimal distance) { - BigDecimal[] roots = SolutionUtils.solveQuadraticEquation(BigDecimal.ONE, time.negate(), distance); + BigDecimal[] roots = MathUtils.solveQuadraticEquation(BigDecimal.ONE, time.negate(), distance); BigDecimal start = roots[0].add(BigDecimal.ONE).setScale(0, RoundingMode.FLOOR); BigDecimal end = roots[1].subtract(BigDecimal.ONE).setScale(0, RoundingMode.CEILING); return end.subtract(start).add(BigDecimal.ONE).toBigInteger(); diff --git a/src/main/java/net/bqc/aoc/year2023/Day08.java b/src/main/java/net/bqc/aoc/year2023/Day08.java index 86f765c..fb8955c 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day08.java +++ b/src/main/java/net/bqc/aoc/year2023/Day08.java @@ -1,7 +1,7 @@ package net.bqc.aoc.year2023; import net.bqc.aoc.Solution; -import net.bqc.aoc.utils.SolutionUtils; +import net.bqc.aoc.utils.MathUtils; import java.util.HashMap; import java.util.List; @@ -32,7 +32,7 @@ public long solve(PART_NUMBER part, List inputLines) { .map(l -> travelInMaps(p, l)) .toList(); - return SolutionUtils.lcm(steps); + return MathUtils.lcm(steps); } } diff --git a/src/main/java/net/bqc/aoc/year2023/Day09.java b/src/main/java/net/bqc/aoc/year2023/Day09.java index 03067b0..c9e428e 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day09.java +++ b/src/main/java/net/bqc/aoc/year2023/Day09.java @@ -15,7 +15,7 @@ public long solve(PART_NUMBER part, List inputLines) { .map(l -> Arrays.stream(l.split("\s")).map(Long::parseLong).toList()) .toList(); - if (part == PART_NUMBER.ONE) { + if (!isPart2()) { return histories.stream().mapToLong(this::predict).sum(); } else { diff --git a/src/main/java/net/bqc/aoc/year2023/Day10.java b/src/main/java/net/bqc/aoc/year2023/Day10.java index 8fb7e6a..78f26f7 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day10.java +++ b/src/main/java/net/bqc/aoc/year2023/Day10.java @@ -43,7 +43,7 @@ public long solve(PART_NUMBER part, List inputLines) { long steps = traversal(matrix, startPos) / 2; - if (part == PART_NUMBER.TWO) { + if (isPart2()) { // Use Shoelace's theorem to compute the area of polygon: // A = 1/2(x1y2 + x2y3 + ... + xny1) - (y1x2 + y2x3 + ... + x1yn) // The area of the polygon can also be computed with Rick's theorem diff --git a/src/main/java/net/bqc/aoc/year2023/Day11.java b/src/main/java/net/bqc/aoc/year2023/Day11.java index acbb9ec..26c732e 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day11.java +++ b/src/main/java/net/bqc/aoc/year2023/Day11.java @@ -14,7 +14,7 @@ public class Day11 extends Solution { public long solve(PART_NUMBER part, List inputLines) { int[][] space = parseSpace(inputLines); List galaxies = findGalaxies(space); - return computeTotalDistance(galaxies, part == PART_NUMBER.ONE ? 2 : 1000000); + return computeTotalDistance(galaxies, !isPart2() ? 2 : 1000000); } private long computeTotalDistance(List galaxies, int expansionRatio) { diff --git a/src/main/java/net/bqc/aoc/year2023/Day13.java b/src/main/java/net/bqc/aoc/year2023/Day13.java index 8bc4ea8..a237eda 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day13.java +++ b/src/main/java/net/bqc/aoc/year2023/Day13.java @@ -16,7 +16,7 @@ public class Day13 extends Solution { public long solve(PART_NUMBER part, List inputLines) { super.solve(part, inputLines); List mirrors = parseMirrors(inputLines); - return summarize(mirrors, part == PART_NUMBER.ONE ? 0 : 1); + return summarize(mirrors, !isPart2() ? 0 : 1); } private long summarize(List mirrors, int acceptedWrongSymbol) { diff --git a/src/main/java/net/bqc/aoc/year2023/Day14.java b/src/main/java/net/bqc/aoc/year2023/Day14.java index 9caf7fb..4fbefcf 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day14.java +++ b/src/main/java/net/bqc/aoc/year2023/Day14.java @@ -1,7 +1,7 @@ package net.bqc.aoc.year2023; import net.bqc.aoc.Solution; -import net.bqc.aoc.utils.SolutionUtils; +import net.bqc.aoc.utils.EncryptionUtils; import java.util.HashMap; import java.util.List; @@ -24,7 +24,7 @@ public long solve(PART_NUMBER part, List inputLines) { int[][] space = parseSpace(inputLines); - if (part == PART_NUMBER.ONE) { + if (!isPart2()) { roll(space, UP); } else { @@ -36,7 +36,7 @@ public long solve(PART_NUMBER part, List inputLines) { long[] loads = new long[1001]; for (int i = 1; i <= 1000; i++) { rollOneCycle(space); - String hash = SolutionUtils.generateSHA256(space); + String hash = EncryptionUtils.generateSHA256(space); loads[i] = calculateTotalLoad(space); if (map.containsKey(hash)) { diff --git a/src/main/java/net/bqc/aoc/year2023/Day15.java b/src/main/java/net/bqc/aoc/year2023/Day15.java index 5602d20..7295feb 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day15.java +++ b/src/main/java/net/bqc/aoc/year2023/Day15.java @@ -22,7 +22,7 @@ public long solve(PART_NUMBER part, List inputLines) { String[] texts = inputLines.get(0).split(","); - if (part == PART_NUMBER.ONE) { + if (!isPart2()) { return Arrays.stream(texts).mapToLong(this::hash).sum(); } else { diff --git a/src/main/java/net/bqc/aoc/year2023/Day16.java b/src/main/java/net/bqc/aoc/year2023/Day16.java index 8dede40..22c74c6 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day16.java +++ b/src/main/java/net/bqc/aoc/year2023/Day16.java @@ -48,7 +48,7 @@ public long solve(PART_NUMBER part, List inputLines) { char[][] map = parseMap(inputLines); - if (part == PART_NUMBER.ONE) { + if (!isPart2()) { visitedPoints = new int[map.length][map[0].length]; move(map, 0, 0, RIGHT); } diff --git a/src/main/java/net/bqc/aoc/year2023/Day17.java b/src/main/java/net/bqc/aoc/year2023/Day17.java index 68d40a4..e24ac6d 100644 --- a/src/main/java/net/bqc/aoc/year2023/Day17.java +++ b/src/main/java/net/bqc/aoc/year2023/Day17.java @@ -146,7 +146,7 @@ public long solve(PART_NUMBER part, List inputLines) { super.solve(part, inputLines); Graph graph = constructGraph(inputLines); - return part == PART_NUMBER.ONE ? graph.minCost(0, 3) : graph.minCost(4, 10); + return !isPart2() ? graph.minCost(0, 3) : graph.minCost(4, 10); } private Graph constructGraph(List inputLines) { diff --git a/src/main/java/net/bqc/aoc/year2024/Day01.java b/src/main/java/net/bqc/aoc/year2024/Day01.java index 8565566..7fe027b 100644 --- a/src/main/java/net/bqc/aoc/year2024/Day01.java +++ b/src/main/java/net/bqc/aoc/year2024/Day01.java @@ -27,7 +27,7 @@ public long solve(PART_NUMBER part, List inputLines) { int sum = 0; for (int i = 0; i < list1.length; i++) { - sum += part == PART_NUMBER.ONE ? Math.abs(list2[i] - list1[i]) : list1[i] * map.getOrDefault(list1[i], 0); + sum += !isPart2() ? Math.abs(list2[i] - list1[i]) : list1[i] * map.getOrDefault(list1[i], 0); } return sum; } diff --git a/src/main/java/net/bqc/aoc/year2024/Day02.java b/src/main/java/net/bqc/aoc/year2024/Day02.java index 9a9d685..95aa450 100644 --- a/src/main/java/net/bqc/aoc/year2024/Day02.java +++ b/src/main/java/net/bqc/aoc/year2024/Day02.java @@ -13,7 +13,7 @@ public class Day02 extends Solution { public long solve(PART_NUMBER part, List inputLines) { super.solve(part, inputLines); - if (part == PART_NUMBER.ONE) return inputLines.stream().filter(this::isSafe).count(); + if (!isPart2()) return inputLines.stream().filter(this::isSafe).count(); return inputLines.stream().filter(this::isSafeWithDampener).count(); } diff --git a/src/main/java/net/bqc/aoc/year2024/Day04.java b/src/main/java/net/bqc/aoc/year2024/Day04.java index 0ca8fdb..5163237 100644 --- a/src/main/java/net/bqc/aoc/year2024/Day04.java +++ b/src/main/java/net/bqc/aoc/year2024/Day04.java @@ -1,8 +1,8 @@ package net.bqc.aoc.year2024; import net.bqc.aoc.Solution; +import net.bqc.aoc.utils.Array2DUtils; import net.bqc.aoc.utils.Pos; -import net.bqc.aoc.utils.SolutionUtils; import java.util.List; @@ -12,14 +12,14 @@ public class Day04 extends Solution { public long solve(PART_NUMBER part, List inputLines) { super.solve(part, inputLines); - char[][] matrix = SolutionUtils.readAsMatrix(inputLines); + char[][] matrix = Array2DUtils.readAsMatrix(inputLines); - if (part == PART_NUMBER.ONE) { - List xPos = SolutionUtils.getXPos(matrix, 'X'); + if (!isPart2()) { + List xPos = Array2DUtils.getXPos(matrix, 'X'); return xPos.stream().map(p -> countXMAS(matrix, p)).reduce(Integer::sum).get(); } - List aPos = SolutionUtils.getXPos(matrix, 'A'); + List aPos = Array2DUtils.getXPos(matrix, 'A'); return aPos.stream().map(p -> countX_MAS(matrix, p)).reduce(Integer::sum).get(); } diff --git a/src/main/java/net/bqc/aoc/year2024/Day05.java b/src/main/java/net/bqc/aoc/year2024/Day05.java index 1ff0a25..9a40604 100644 --- a/src/main/java/net/bqc/aoc/year2024/Day05.java +++ b/src/main/java/net/bqc/aoc/year2024/Day05.java @@ -17,7 +17,7 @@ public long solve(PART_NUMBER part, List inputLines) { List> chosenUpdates; - if (part == PART_NUMBER.ONE) { + if (!isPart2()) { chosenUpdates = this.printUpdates.stream().filter(this::isValidUpdate).toList(); } else { diff --git a/src/main/java/net/bqc/aoc/year2024/Day06.java b/src/main/java/net/bqc/aoc/year2024/Day06.java index 0c09d90..63f37fe 100644 --- a/src/main/java/net/bqc/aoc/year2024/Day06.java +++ b/src/main/java/net/bqc/aoc/year2024/Day06.java @@ -1,9 +1,9 @@ package net.bqc.aoc.year2024; import net.bqc.aoc.Solution; +import net.bqc.aoc.utils.Array2DUtils; import net.bqc.aoc.utils.Pair; import net.bqc.aoc.utils.Pos; -import net.bqc.aoc.utils.SolutionUtils; import java.util.Arrays; import java.util.HashSet; @@ -54,12 +54,12 @@ public boolean isOpposite(Direction o) { @Override public long solve(PART_NUMBER part, List inputLines) { super.solve(part, inputLines); - this.matrix = SolutionUtils.readAsMatrix(inputLines); + this.matrix = Array2DUtils.readAsMatrix(inputLines); Pair start = findStartingPos(matrix); patrol(start.first, start.second); - return part == PART_NUMBER.ONE ? SolutionUtils.countInMatrix(matrix, 'X') : loopCount; + return !isPart2() ? Array2DUtils.countInMatrix(matrix, 'X') : loopCount; } private void patrol(Pos pos, Direction direction) { @@ -78,7 +78,7 @@ else if (matrix[newX][newY] == '#') { } else { if (matrix[newX][newY] == '.') { - char[][] tmpMatrix = SolutionUtils.copyMatrix(matrix); + char[][] tmpMatrix = Array2DUtils.copyMatrix(matrix); tmpMatrix[newX][newY] = 'O'; if (checkLoop(tmpMatrix, new HashSet<>(visited), pos, direction)) { // System.out.printf("%d,%d %s\n", pos.x, pos.y, direction.symbol); diff --git a/src/main/java/net/bqc/aoc/year2024/Day08.java b/src/main/java/net/bqc/aoc/year2024/Day08.java index 2a5eed6..1843bc7 100644 --- a/src/main/java/net/bqc/aoc/year2024/Day08.java +++ b/src/main/java/net/bqc/aoc/year2024/Day08.java @@ -1,7 +1,7 @@ package net.bqc.aoc.year2024; import net.bqc.aoc.Solution; -import net.bqc.aoc.utils.SolutionUtils; +import net.bqc.aoc.utils.Array2DUtils; import java.util.List; @@ -13,7 +13,7 @@ public class Day08 extends Solution { public long solve(PART_NUMBER part, List inputLines) { super.solve(part, inputLines); - this.antennas = SolutionUtils.readAsMatrix(inputLines); + this.antennas = Array2DUtils.readAsMatrix(inputLines); int[][] antinodes = generateAntinodes(); if (isPart2()) { @@ -24,13 +24,13 @@ public long solve(PART_NUMBER part, List inputLines) { } } } - return SolutionUtils.sum(antinodes); + return Array2DUtils.sum(antinodes); } private int[][] generateAntinodes() { int m = antennas.length; int n = antennas[0].length; - int[][] antinotes = SolutionUtils.generateMatrix(m, n); + int[][] antinotes = Array2DUtils.generateMatrix(m, n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (antennas[i][j] == '.') continue;