Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AdventOfCodeData
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.example.adventofcode.year2025.day09;

import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.example.adventofcode.utils.FileUtils.readLines;

public class MovieTheater {
private static final String FILENAME = "AdventOfCodeData/2025/day09/input";
private static final String EXAMPLE_FILENAME = "AdventOfCodeData/2025/day09/example_input";

public static void main(String[] args) throws IOException {
System.out.println(calculateLargestAreaBruteForce(EXAMPLE_FILENAME));
System.out.println(calculateLargestAreaBruteForce(FILENAME));
System.out.println(calculateLargestArea(EXAMPLE_FILENAME));
System.out.println(calculateLargestArea(FILENAME));
System.out.println(calculateLargestAreaInsideOfPolygon(EXAMPLE_FILENAME));
System.out.println(calculateLargestAreaInsideOfPolygon(FILENAME));
}


record Point(int x, int y) {
}

public static long calculateLargestAreaBruteForce(final String filename) throws IOException {
List<String> lines = readLines(filename);
List<Point> points = parsePoints(lines);

long maxArea = 0;
for (Point p1 : points) {
for (Point p2 : points) {
long area = (long) (Math.abs(p1.x - p2.x) + 1) * (Math.abs(p1.y - p2.y) + 1);
if (area > maxArea) {
maxArea = area;
}
}
}

return maxArea;
}

public static long calculateLargestArea(final String filename) throws IOException {
List<String> lines = readLines(filename);
List<Point> points = parsePoints(lines);

Set<Rectangle> rectangles = calculateRectangles(points);

long maxArea = 0;
for (Rectangle rectangle : rectangles) {
long area = (long) (rectangle.getHeight() + 1) * (long) (rectangle.getWidth() + 1);
if (area > maxArea) {
maxArea = area;
}
}

return maxArea;
}

public static long calculateLargestAreaInsideOfPolygon(final String filename) throws IOException {
List<String> lines = readLines(filename);
List<Point> points = parsePoints(lines);

Polygon polygon = calculatePolygon(points);
Set<Rectangle> rectangles = calculateRectangles(points);

long maxArea = 0;
for (Rectangle rectangle : rectangles) {
long area = (long) (rectangle.getHeight() + 1) * (long) (rectangle.getWidth() + 1);

if (polygon.contains(
rectangle.getX() + 1,
rectangle.getY() + 1,
rectangle.getWidth() - 1,
rectangle.getHeight() - 1) && area > maxArea) {
maxArea = area;
}
}

return maxArea;
}

private static List<Point> parsePoints(List<String> lines) {
List<Point> points = new ArrayList<>();
for (String line : lines) {
String[] p = line.split(",");
points.add(new Point(Integer.parseInt(p[0]), Integer.parseInt(p[1])));
}
return points;
}

private static Set<Rectangle> calculateRectangles(List<Point> points) {
Set<Rectangle> rectangles = new HashSet<>();
for (Point p1 : points) {
for (Point p2 : points) {
rectangles.add(new Rectangle(
Math.min(p1.x, p2.x),
Math.min(p1.y, p2.y),
Math.abs(p1.x - p2.x),
Math.abs(p1.y - p2.y)
));
}
}
return rectangles;
}

private static Polygon calculatePolygon(List<Point> points) {
Polygon polygon = new Polygon();
for (Point p : points) {
polygon.addPoint(p.x, p.y);
}
return polygon;
}
}
102 changes: 102 additions & 0 deletions src/main/java/com/example/adventofcode/year2025/day11/Reactor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.example.adventofcode.year2025.day11;

import java.io.IOException;
import java.util.*;

import static com.example.adventofcode.utils.FileUtils.readLines;

public class Reactor {
private static final String FILENAME = "AdventOfCodeData/2025/day11/input";
private static final String EXAMPLE_FILENAME = "AdventOfCodeData/2025/day11/example_input";
private static final String EXAMPLE_FILENAME2 = "AdventOfCodeData/2025/day11/example_input2";

public static void main(String[] args) throws IOException {
System.out.println(countWaysOut(EXAMPLE_FILENAME));
System.out.println(countWaysOut(FILENAME));
System.out.println(countWaysOutThroughNodesSubset(EXAMPLE_FILENAME2));
System.out.println(countWaysOutThroughNodesSubset(FILENAME));
}

record NodeWithPaths(String next, List<String> path) {
}

record NodeCache(String next, boolean seenDac, boolean seenFft) {
}

public static long countWaysOut(final String filename) throws IOException {
List<String> lines = readLines(filename);
Map<String, List<String>> nodes = parseNodes(lines);

Deque<NodeWithPaths> queue = new ArrayDeque<>();
for (String node : nodes.get("you")) {
queue.add(new NodeWithPaths(node, new ArrayList<>()));
}

int count = 0;
while (!queue.isEmpty()) {
NodeWithPaths current = queue.poll();
current.path.add(current.next);

for (String neighbour : nodes.get(current.next)) {
if (neighbour.equals("out")) {
count++;
} else if (!current.path.contains(neighbour)) {
queue.add(new NodeWithPaths(neighbour, new ArrayList<>(current.path)));
}
}
}

return count;
}

public static long countWaysOutThroughNodesSubset(final String filename) throws IOException {
List<String> lines = readLines(filename);
Map<String, List<String>> nodes = parseNodes(lines);

return countWaysOutThroughNodesSubset(new NodeCache("svr", false, false), nodes, new HashMap<>());
}

private static Map<String, List<String>> parseNodes(List<String> lines) {
Map<String, List<String>> nodes = new HashMap<>();
for (String line : lines) {
String[] targetingArray = line.split(":")[1].substring(1).split(" ");
List<String> targeting = Arrays.asList(targetingArray);

nodes.put(line.split(":")[0], targeting);
}
return nodes;
}

private static long countWaysOutThroughNodesSubset(NodeCache node, Map<String, List<String>> nodes, Map<NodeCache, Long> cache) {
String nodeName = node.next;
boolean seenDac = node.seenDac;
boolean seenFft = node.seenFft;
switch (nodeName) {
case "out" -> {
if (node.seenDac && node.seenFft) {
return 1;
} else {
return 0;
}
}
case "dac" -> seenDac = true;
case "fft" -> seenFft = true;
}

long sumOut = 0;
for (String nextNode : nodes.get(nodeName)) {
sumOut += countWaysOutThroughNodesSubsetWithCache(new NodeCache(nextNode, seenDac, seenFft), nodes, cache);
}
return sumOut;
}

private static long countWaysOutThroughNodesSubsetWithCache(NodeCache node, Map<String, List<String>> nodes, Map<NodeCache, Long> cache) {
if (cache.containsKey(node)) {
return cache.get(node);
}

long result = countWaysOutThroughNodesSubset(node, nodes, cache);
cache.put(node, result);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.example.adventofcode.year2025.day09;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MovieTheaterTest {

private static Stream<Arguments> filepathsAndConnectionsAndExpectedLargestArea() {
return Stream.of(
Arguments.of("AdventOfCodeData/2025/day09/example_input", 50),
Arguments.of("AdventOfCodeData/2025/day09/input", 4769758290L)
);
}

@ParameterizedTest
@MethodSource("filepathsAndConnectionsAndExpectedLargestArea")
void calculateLargestAreaBruteForce(final String filename,
final long expectedLargestArea) throws IOException {
assertEquals(expectedLargestArea, MovieTheater.calculateLargestAreaBruteForce(filename));
}

@ParameterizedTest
@MethodSource("filepathsAndConnectionsAndExpectedLargestArea")
void calculateLargestArea(final String filename,
final long expectedLargestArea) throws IOException {
assertEquals(expectedLargestArea, MovieTheater.calculateLargestArea(filename));
}

private static Stream<Arguments> filepathsAndConnectionsAndExpectedLargestAreaInsideOfPolygon() {
return Stream.of(
Arguments.of("AdventOfCodeData/2025/day09/example_input", 24),
Arguments.of("AdventOfCodeData/2025/day09/input", 1588990708L)
);
}

@ParameterizedTest
@MethodSource("filepathsAndConnectionsAndExpectedLargestAreaInsideOfPolygon")
void calculateLargestAreaInsideOfPolygon(final String filename,
final long expectedLargestArea) throws IOException {
assertEquals(expectedLargestArea, MovieTheater.calculateLargestAreaInsideOfPolygon(filename));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.adventofcode.year2025.day11;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

class ReactorTest {

private static Stream<Arguments> filepathsAndConnectionsAndExpectedWaysOut() {
return Stream.of(
Arguments.of("AdventOfCodeData/2025/day11/example_input", 5),
Arguments.of("AdventOfCodeData/2025/day11/input", 615)
);
}

@ParameterizedTest
@MethodSource("filepathsAndConnectionsAndExpectedWaysOut")
void countWaysOut(final String filename,
final long expectedWaysOut) throws IOException {
assertEquals(expectedWaysOut, Reactor.countWaysOut(filename));
}

private static Stream<Arguments> filepathsAndConnectionsAndExpectedWaysOutThroughNodesSubset() {
return Stream.of(
Arguments.of("AdventOfCodeData/2025/day11/example_input2", 2),
Arguments.of("AdventOfCodeData/2025/day11/input", 303012373210128L)
);
}

@ParameterizedTest
@MethodSource("filepathsAndConnectionsAndExpectedWaysOutThroughNodesSubset")
void countWaysOutThroughNodesSubset(final String filename,
final long expectedWaysOut) throws IOException {
assertEquals(expectedWaysOut, Reactor.countWaysOutThroughNodesSubset(filename));
}
}
Loading