1
0

Day 5 initial

This commit is contained in:
2025-12-06 17:58:32 +01:00
commit 2ac9f10c15
6 changed files with 1423 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

35
pom.xml Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.7zzcx7.de</groupId>
<artifactId>advent_of_code_2025</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<scmDeveloperConnectionProp />
</properties>
<distributionManagement>
<snapshotRepository>
<id>77zzcx7-snapshots</id>
<url>http://192.168.10.4:8100/snapshots/</url>
</snapshotRepository>
<repository>
<id>77zzcx7-releases</id>
<url>http://192.168.10.4:8100/releases/</url>
</repository>
</distributionManagement>
<scm>
<connection>scm:git:https://gitea.77zzcx7.de/MK13/advent_of_code_2025.git</connection>
<developerConnection>${scmDeveloperConnectionProp}</developerConnection>
<url>https://gitea.77zzcx7.de/MK13/advent_of_code_2025</url>
</scm>
</project>

View File

@@ -0,0 +1,133 @@
package de.advent_of_code_2025.five;
import de.advent_of_code_2025.util.InputMangler;
import de.advent_of_code_2025.util.InputReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.LongStream;
public class Main {
private static final record IngredientRange(Long start, Long end) {
public boolean containsIngredientId(Long ingredientId) {
return isInRange(ingredientId);
}
public boolean isInRange(Long id) {
return start <= id && end >= id;
}
public IngredientRange merge(IngredientRange other) {
if(Objects.equals(start, other.start) && Objects.equals(end, other.end)) {
return new IngredientRange(start, end);
}
else if(isInRange(other.start) || isInRange(other.end)) {
return new IngredientRange(Math.min(start, other.start), Math.max(end, other.end));
}
else {
return null;
}
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
IngredientRange that = (IngredientRange) o;
return Objects.equals(end, that.end) && Objects.equals(start, that.start);
}
@Override
public int hashCode() {
return Objects.hash(start, end);
}
}
public static void main(String[] args) throws Throwable {
final List<String> lines = InputReader.read(args);
final List<List<String>> lists = InputMangler.mangle(lines, String::isBlank);
final List<Long> ingredientIds = new ArrayList<>();
final List<IngredientRange> ingredientRanges = new ArrayList<>();
final AtomicInteger freshIngredientCount = new AtomicInteger(0);
// Ingredient IDs
lists.get(1).stream().map(Long::parseLong).forEach(ingredientIds::add);
// Fresh ingredient ID ranges
lists.get(0).stream()
.map(ingredientRangeString -> ingredientRangeString.split("-"))
.map(rangeString -> new IngredientRange(Long.parseLong(rangeString[0]), Long.parseLong(rangeString[1])))
.forEach(ingredientRanges::add);
// Part 1
for(Long ingredientId : ingredientIds) {
for(IngredientRange ingredientRange : ingredientRanges) {
if(ingredientRange.containsIngredientId(ingredientId)) {
freshIngredientCount.incrementAndGet();
break;
}
}
}
System.out.println(freshIngredientCount.get());
// Part 2
final AtomicLong soManyFreshCount = new AtomicLong(0);
final Set<IngredientRange> concurrentSet = ConcurrentHashMap.newKeySet();
concurrentSet.addAll(ingredientRanges);
reduce(concurrentSet);
for(IngredientRange ingredientRange : concurrentSet) {
soManyFreshCount.set(soManyFreshCount.get() + LongStream.range(ingredientRange.start, ingredientRange.end + 1).count());
}
System.out.println(soManyFreshCount.get());
}
private static final void reduce(Collection<IngredientRange> originalRanges) {
boolean atLeastOneMerged = false;
for(IngredientRange ingredientRange : originalRanges) {
for(IngredientRange ingredientRange1 : originalRanges) {
if(ingredientRange == ingredientRange1) {
continue;
}
IngredientRange overlap = ingredientRange.merge(ingredientRange1);
if(overlap != null) {
atLeastOneMerged = true;
boolean added = originalRanges.add(overlap);
if(!added) {
if(!overlap.equals(ingredientRange)) {
originalRanges.remove(ingredientRange);
}
if(!overlap.equals(ingredientRange1)) {
originalRanges.remove(ingredientRange1);
}
}
else {
originalRanges.remove(ingredientRange1);
originalRanges.remove(ingredientRange);
}
}
// else: the ranges do not overlap
}
}
if(!atLeastOneMerged) { // if nothing overlaps anymore we are done
return;
}
reduce(originalRanges);
}
}

View File

@@ -0,0 +1,30 @@
package de.advent_of_code_2025.util;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class InputMangler {
public static final List<List<String>> mangle(List<String> inputList, Predicate<String> predicate) {
final List<List<String>> retVal = new ArrayList<>();
List<String> current = null;
for(String line : inputList) {
if(current == null) {
current = new ArrayList<>();
retVal.add(current);
}
if(predicate.test(line)) {
current = null;
continue;
}
current.add(line);
}
return retVal;
}
}

View File

@@ -0,0 +1,13 @@
package de.advent_of_code_2025.util;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class InputReader {
public static final List<String> read(String[] args) throws IOException {
final String fileName = args[0];
return Files.readAllLines(Paths.get(fileName));
}
}

File diff suppressed because it is too large Load Diff