{"id":54130,"date":"2025-12-05T08:46:36","date_gmt":"2025-12-05T07:46:36","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=54130"},"modified":"2025-12-15T08:43:47","modified_gmt":"2025-12-15T07:43:47","slug":"advent-of-code-2025","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/algorithmen\/advent-of-code-2025\/","title":{"rendered":"Advent\u00a0of\u00a0Code 2025\u00a0\u2013 Java L\u00f6sungen"},"content":{"rendered":"\n<p>Dieses Jahr habe ich wieder beim <a href=\"https:\/\/adventofcode.com\/2025\" target=\"_blank\" rel=\"noopener\"><em>Advent of Code<\/em><\/a> mitgemacht. In diesem Artikel findest du meine L\u00f6sungen. Mein Ziel ist es, die L\u00f6sungen m\u00f6glichst verst\u00e4ndlich zu implementieren, nicht m\u00f6glichst \u201esmart\u201c oder kurz. Ich setze <a href=\"https:\/\/www.sonarsource.com\/products\/sonarqube\/\" target=\"_blank\" rel=\"noopener\">SonarQube<\/a> ein, um eine m\u00f6glichst hohe Code-Qualit\u00e4t zu erreichen.<\/p>\n\n\n\n<p>Ich werden au\u00dferdem versuchen, m\u00f6glichst viele Features des aktuellen <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-25-features\/\">Java 25<\/a> zu verwenden \u2013 einschlie\u00dflich Preview-Features.<\/p>\n\n\n\n<p>Wer <em>Advent of Code<\/em> noch nicht kennt: Es gibt \u2013 in eine vorweihnachtliche Geschichte verpackt \u2013 jeden Tag eine Programmieraufgabe. Oder besser gesagt: jeden Tag zwei \u2013 n\u00e4mlich eine, die sich recht schnell l\u00f6sen l\u00e4sst \u2013 und eine zweite, bei der einem in der Regel die <a href=\"https:\/\/www.happycoders.eu\/de\/algorithmen\/o-notation-zeitkomplexitaet\/\">Zeit- oder Platzkomplexit\u00e4t<\/a> der ersten L\u00f6sung einen Strich durch die Rechnung macht \u2026 und man noch mal von vorne \u00fcberlegen muss.<\/p>\n\n\n\n<p>Die L\u00f6sungen findest du in diesem GitHub-Projekt:&nbsp;<a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Java 25 Solutions<\/a>.<\/p>\n\n\n\n<p>Hier findest du meine L\u00f6sungen f\u00fcr <a href=\"https:\/\/www.happycoders.eu\/de\/algorithmen\/advent-of-code-2015\/\">Advent of Code 2015<\/a> und <a href=\"https:\/\/www.happycoders.eu\/de\/algorithmen\/advent-of-code-2022\/\">Advent of Code 2022<\/a>.<\/p>\n\n\n\n<p>Und jetzt geht's los!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-1-java-loesung\">Advent of Code 2025 \u2013 Tag 1 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/1\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 1 Aufgabe<\/a><\/p>\n\n\n\n<p>Advent of Code 2025 beginnt recht knifflig!<\/p>\n\n\n\n<p>Wir beginnen mit einem Parser f\u00fcr die Rotation:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">parseRotation<\/span><span class=\"hljs-params\">(String s)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> multiplicator = s.charAt(<span class=\"hljs-number\">0<\/span>) == <span class=\"hljs-string\">'R'<\/span> ? <span class=\"hljs-number\">1<\/span> : -<span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-keyword\">return<\/span> multiplicator * Integer.parseInt(s.substring(<span class=\"hljs-number\">1<\/span>));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"teil-1\">Teil 1<\/h3>\n\n\n\n<p>Teil 1 ist noch schnell gel\u00f6st: wir m\u00fcssen f\u00fcr jede Zeile der Eingabe die Rotationen ausf\u00fchren und immer dann einen Counter hochz\u00e4hlen, wenn nach der Rotation der Zeiger auf der Null steht:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">position = Math.floorMod(position + rotation, DIAL_SIZE);\n<span class=\"hljs-keyword\">if<\/span> (position == <span class=\"hljs-number\">0<\/span>) {\n  zeroCount++;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Wichtig ist dabei, dass wir <code>Math.floorMod(...)<\/code> verwenden und nicht den <code>%<\/code>-Operator, denn der berechnet in Java nicht den Modulo, sondern den Rest nach einer Teilung. Beispielsweise ergibt <code>-140 % 100<\/code> nicht etwa 60, sondern -40. Um 60 zu erhalten, m\u00fcssen wir <code>Math.floorMod(-140, 100)<\/code> aufrufen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"teil-2\">Teil 2<\/h3>\n\n\n\n<p>Teil 2 m\u00fcssen wir komplett anders angehen. Zun\u00e4chst einmal berechnen wir die neue Position ohne die Modulo-Operation:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">position += rotation;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Jetzt m\u00fcssen wir unterscheiden, ob wir rechts oder links herum gedreht haben. Bei einer Rechts-Rotation ist die Berechnung einfach: die H\u00e4ufigkeit, mit der der Zeiger auf die Null gezeigt hat, ist die Position geteilt durch <code>DIAL_SIZE<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">if<\/span> (rotation &gt; <span class=\"hljs-number\">0<\/span>) {\n  zeroCount += position \/ DIAL_SIZE;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Bei einer Links-Rotation ist die Berechnung komplizierter:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">else<\/span> {\n  zeroCount += (DIAL_SIZE - position) \/ DIAL_SIZE;\n\n  <span class=\"hljs-keyword\">boolean<\/span> startedAtZero = position - rotation == <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-keyword\">if<\/span> (startedAtZero) {\n    zeroCount--;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Da wir mit einer negativen Zahl arbeiten, m\u00fcssen wir diese zun\u00e4chst von <code>DIAL_SIZE<\/code> subtrahieren. Dann ist noch ein Sonderfall zu beachten: Wenn der Zeiger zu Beginn der Operation auf Null steht, w\u00fcrde diese Null mitgez\u00e4hlt werden. Deshalb m\u00fcssen wir in diesem Fall eine Null abziehen.<\/p>\n\n\n\n<p>Der <code>else<\/code>-Block lie\u00dfe sich auch \u201esmart\u201c wie folgt schreiben:  <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">else<\/span> {\n  zeroCount += (DIAL_SIZE - position) \/ DIAL_SIZE - (position - rotation == <span class=\"hljs-number\">0<\/span> ? <span class=\"hljs-number\">1<\/span> : <span class=\"hljs-number\">0<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Ich halte aber die erste, etwas l\u00e4ngere Variante f\u00fcr deutlich besser lesbar.<\/p>\n\n\n\n<p>Zum Schluss m\u00fcssen wir die Position wieder auf den Zahlenbereich 0\u201399 \u201enormalisieren\u201c:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">position = Math.floorMod(position, DIAL_SIZE);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die vollst\u00e4ndige L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day1\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 1 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-2-java-loesung\">Advent of Code 2025 \u2013 Tag 2 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/2\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 2 Aufgabe<\/a><\/p>\n\n\n\n<p>F\u00fcr Tag 2 schreibe ich zun\u00e4chst einen <code>Range<\/code>-Klasse, die eine Zeile der Eingabe parsen und einen Stream aller Zahlen des Zahlenbereichs zur\u00fcckgeben kann (diese Klasse werden wir praktischerweise an sp\u00e4teren Tagen wiederverwenden k\u00f6nnen):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Range<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">long<\/span> from, <span class=\"hljs-keyword\">long<\/span> to)<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Range <span class=\"hljs-title\">parse<\/span><span class=\"hljs-params\">(String s)<\/span> <\/span>{\n    String&#091;] split = s.split(<span class=\"hljs-string\">\"-\"<\/span>);\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Range(Long.parseLong(split&#091;<span class=\"hljs-number\">0<\/span>]), Long.parseLong(split&#091;<span class=\"hljs-number\">1<\/span>]));\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> LongStream <span class=\"hljs-title\">ids<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> LongStream.rangeClosed(from, to);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Teil 1 und 2 unterscheiden sich durch die maximale Anzahl Wiederholungen innerhalb einer ID. Bei Teil 1 sind es zwei Wiederholungen, bei Teil 2 gibt es keine Begrenzung \u2013 ich verwende <code>Integer.MAX_VALUE<\/code>.<\/p>\n\n\n\n<p>Damit kann ich schon mal eine Hauptfunktion schreiben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">solve<\/span><span class=\"hljs-params\">(String input, <span class=\"hljs-keyword\">int<\/span> maxRepetitions)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> Stream.of(input.split(<span class=\"hljs-string\">\",\"<\/span>))\n      .map(Range::parse)\n      .flatMapToLong(Range::ids)\n      .filter(id -&gt; isInvalidId(id, maxRepetitions))\n      .sum();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Jetzt brauchen wir nur noch eine <code>isInvalidId(...)<\/code>-Methode. <\/p>\n\n\n\n<p>Ich zeige sie dir zun\u00e4chst und erkl\u00e4re sie danach:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">isInvalidId<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">long<\/span> id, <span class=\"hljs-keyword\">int<\/span> maxRepetitions)<\/span> <\/span>{\n  String idString = Long.toString(id);\n  <span class=\"hljs-keyword\">int<\/span> idLength = idString.length();\n  <span class=\"hljs-keyword\">int<\/span> minSequenceLength = Math.ceilDiv(idLength, maxRepetitions);\n  <span class=\"hljs-keyword\">int<\/span> maxSequenceLength = idLength \/ <span class=\"hljs-number\">2<\/span>;\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> sequenceLength = minSequenceLength; \n       sequenceLength &lt;= maxSequenceLength; \n       sequenceLength++) {\n    <span class=\"hljs-keyword\">if<\/span> (containsOnlyRepetitions(idString, idLength, sequenceLength)) {\n      <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n    }\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Zun\u00e4chst wird hier die minmale und maximale L\u00e4nge der sich wiederholenden Teilsequenz berechnet:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Die <em>minimale<\/em> L\u00e4nge ist die L\u00e4nge der ID geteilt durch die <em>maximale<\/em> Anzahl an Wiederholungen (und das ganze aufgerundet). F\u00fcr Teil 1 w\u00e4re das die H\u00e4lfte der ID-L\u00e4nge, f\u00fcr Teil 2 in der Praxis immer 1, da <code>maxRepitions<\/code> dort ja <code>Integer.MAX_VALUE<\/code> Ist.  <\/li>\n\n\n\n<li>Die <em>maximale<\/em> L\u00e4nge ist die L\u00e4nge der ID geteilt durch die <em>minimale<\/em> Anzahl an Wiederholungen (und das ganze abgerundet) \u2013 und die minimale Anzahl an Wiederholungen ist bei beiden Teilen der Aufgabe 2.<\/li>\n<\/ul>\n\n\n\n<p>Dann iterieren wir von der minimalen zur maximalen L\u00e4nge und pr\u00fcfen, ob die ID nur aus Wiederholungen von Teilsequenzen eben dieser L\u00e4nge besteht. <\/p>\n\n\n\n<p>Und das passiert in der folgenden Methode, <code>containsOnlyRepetitions(...)<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">containsOnlyRepetitions<\/span><span class=\"hljs-params\">(String idString,\n                                               <span class=\"hljs-keyword\">int<\/span> idLength,\n                                               <span class=\"hljs-keyword\">int<\/span> sequenceLength)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">if<\/span> (idLength % sequenceLength != <span class=\"hljs-number\">0<\/span>) {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\n  }\n\n  String sequence = idString.substring(<span class=\"hljs-number\">0<\/span>, sequenceLength);\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = sequenceLength; i &lt; idLength; i += sequenceLength) {\n    <span class=\"hljs-keyword\">if<\/span> (!sequence.equals(idString.substring(i, i + sequenceLength))) {\n      <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\n    }\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Zu Beginn pr\u00fcfen wir, ob die L\u00e4nge der ID ein Vielfaches von der L\u00e4nge der Teilsequenz ist. Wenn nicht, k\u00f6nnen wir direkt <code>false<\/code> zur\u00fcckgeben (das w\u00e4re z. B. der Fall, wenn die L\u00e4nge der ID 9 ist und die L\u00e4nge der Teilsequenzen 2). <\/p>\n\n\n\n<p>Danach bestimmen wir die Teilsequenz und pr\u00fcfen mit einer simplen Schleife, ob die ID nur aus diesen Teilsequenzen besteht.<\/p>\n\n\n\n<p>Die vollst\u00e4ndige L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day2\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 2 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-3-java-loesung\">Advent of Code 2025 \u2013 Tag 3 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/3\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 3 Aufgabe<\/a><\/p>\n\n\n\n<p>Tag 3 l\u00e4sst sich mit einem relativ simplen Algorithmus l\u00f6sen.<\/p>\n\n\n\n<p>Wir iterieren \u00fcber die Anzahl der Batterien, die wir zusammenschalten wollen \u2013 und suchen in jeder Iteration in der Batterie-Bank das erste Vorkommnis der gr\u00f6\u00dften noch verbleibenden Zahl. Dabei starten wir rechts von der zuletzt verwendeten Batterie und enden bei [Bankgr\u00f6\u00dfe minus Anzahl noch ben\u00f6tigter Batterien].<\/p>\n\n\n\n<p>Ich zeige dir das am Beispiel der Batterie-Bank <em>234234234234278<\/em> (L\u00e4nge: 15) und der 12 als Anzahl an zusammengeschalteten Batterien:<\/p>\n\n\n\n<p>Wir suchen in den ersten <em>vier<\/em> Batterien nach der gr\u00f6\u00dften (um danach noch mindestens elf weitere Batterien zur Verf\u00fcgung zu haben):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">234234234234278\n^^^^<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die gr\u00f6\u00dfte Zahl ist die 4 an der dritten Position \u2013 die Batterien davor k\u00f6nnen wir ignorieren (durch einen Punkt ersetzt):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">..4234234234278\n  ^<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die restlichen elf Batterien m\u00fcssen wir im verbleibenden Bereich <em>234234234278<\/em> (L\u00e4nge: 12) suchen. Dieses Mal d\u00fcrfen wir nur in den ersten <em>zwei<\/em> Batterien nach der gr\u00f6\u00dften suchen, um danach noch mindestens zehn weitere zu haben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">..4234234234278 \n   ^^<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die gr\u00f6\u00dfte Zahl ist die 3 \u2013 die davor k\u00f6nnen wir wieder ignorieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">..4.34234234278 \n    ^ <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Nach der 3 verbleiben zehn weitere Batterien. Wir brauchen insgesamt zw\u00f6lf, haben zwei, also brauchen wir noch alle zehn verbleibenden:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">..4.34234234278 \n     ^^^^^^^^^^<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und damit haben wir das Ergebnis: <em>434234234278<\/em><\/p>\n\n\n\n<p>Die Implementierung dieses Algorithmus findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day3\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 3 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-4-java-loesung\">Advent of Code 2025 \u2013 Tag 4 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/4\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 4 Aufgabe<\/a><\/p>\n\n\n\n<p>An Tag 4 k\u00f6nnen wir das Entfernen der Rollen durch den Gabelstapler einfach simulieren. \u00dcber einen speziellen Algorithmus m\u00fcssen wir uns heute nicht den Kopf zerbrechen.<\/p>\n\n\n\n<p>Wir iterieren dazu \u00fcber die gesamte Eingabematrix und z\u00e4hlen f\u00fcr jedes Feld die benachbarten Rollen. Sind es weniger als 4, markieren wir das Feld als erreichbar (oder speichern es in einer Liste).<\/p>\n\n\n\n<p>F\u00fcr Teil 1 geben wir die Anzahl erreichbarer Felder zur\u00fcck.<\/p>\n\n\n\n<p>F\u00fcr Teil 2 entfernen wir sie aus der Matrix und wiederholen den gesamten Prozess \u2013 so lange, bis keine weiteren Rollen entfernt werden k\u00f6nnen.<\/p>\n\n\n\n<p>Meine L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day4\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 4 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-5-java-loesung\">Advent of Code 2025 \u2013 Tag 5 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/5\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 5 Aufgabe<\/a><\/p>\n\n\n\n<p>An Tag 5 k\u00f6nnen wir die <code>Range<\/code>-Klasse von Tag 1 wiederverwenden und erweitern!<\/p>\n\n\n\n<p>F\u00fcr Teil 1 f\u00fcgen wir eine <code>contains(...)<\/code>-Methode ein, mit der wir dann einfach f\u00fcr alle Zutaten pr\u00fcfen, ob sie in den Ranges der frischen Zutaten enthalten sind:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> record <span class=\"hljs-title\">Range<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">long<\/span> from, <span class=\"hljs-keyword\">long<\/span> to)<\/span> <\/span>{\n  . . .\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">contains<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">long<\/span> value)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> value &gt;= from &amp;&amp; value &lt;= to;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Teil 2 h\u00f6rt sich erstmal simpel an: M\u00fcssen wir einfach nur die L\u00e4ngen aller Ranges aufaddieren?<\/p>\n\n\n\n<p>Nat\u00fcrlich nicht ;-)<\/p>\n\n\n\n<p>Denn die Ranges \u00fcberschneiden sich teilweise \u2013 und die Zutaten der sich \u00fcberschneidenen Bereiche w\u00fcrden wir so mehrfach z\u00e4hlen.<\/p>\n\n\n\n<p>Anstatt nun die sich \u00fcberschneidenen Bereiche wieder herauszurechnen, bin ich einen anderen Weg gegangen: Ich habe ein <code>RangeSet<\/code> implementiert, das nur disjunkte Ranges enthalten darf \u2013 also solche, die sich <em>nicht<\/em> \u00fcberschneiden. Diesem <code>RangeSet<\/code> werden alle Ranges hinzugef\u00fcgt \u2013 und beim Hinzuf\u00fcgen pr\u00fcft das <code>RangeSet<\/code>, ob sich der hinzugef\u00fcgte Range mit einem der bestehenden Ranges \u00fcberschneidet. Wenn ja, werden bestehender Range und hinzugef\u00fcgter Range gemerged. Hier ein Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Ranges im Set:      ....xxxxx........xxxxxx......xxxxx....\nNeuer Range:        .......xxxxx..........................\n\nGemergter Range:        xxxxxxxx\n\nRanges nach Merge:  ....xxxxxxxx.....xxxxxx......xxxxx....<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Jetzt kann es allerdings auch passieren, dass der neue Range sich mit <em>mehreren<\/em> bestehenden Ranges \u00fcberschneidet. Daher wird f\u00fcr den gemergten Range erneut gepr\u00fcft, ob dieser sich mit den bestehenden Ranges \u00fcberschneidet und ggf. noch einmal gemerged. Das wird solange wiederholt, bis es keine \u00dcberschneidungen mehr gibt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Ranges im Set:      ....xxxxx........xxxxxx......xxxxx....\nNeuer Range:        .......xxxxxxxxxxxxx..................\n\n1. gemergter Range:     xxxxxxxxxxxxxxxx\n2. gemergter Range:     xxxxxxxxxxxxxxxxxxx\n\nRanges nach Merge:  ....xxxxxxxxxxxxxxxxxxx......xxxxx....<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Beim Mergen zweier Ranges m\u00fcssen vier F\u00e4lle unterschieden werden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Range 1 enth\u00e4lt Range 2 vollst\u00e4ndig<\/li>\n\n\n\n<li>Range 2 enth\u00e4lt Range 1 vollst\u00e4ndig<\/li>\n\n\n\n<li>Range 1 \u00fcberschneidet sich, von links kommend, mit Range 2 (oder ber\u00fchrt Range 2)<\/li>\n\n\n\n<li>Range 2 \u00fcberschneidet sich, von links kommend, mit Range 1 (oder ber\u00fchrt Range 1) <\/li>\n<\/ul>\n\n\n\n<p>Nachdem so alle Ranges von frischen Zutaten dem <code>RangeSet<\/code> hinzugef\u00fcgt und \u00dcberschneidungen gemerged wurden, m\u00fcssen wir tats\u00e4chlich nur noch die L\u00e4ngen aller diskunkten Ranges aufaddieren.<\/p>\n\n\n\n<p>Meine L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day6\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 6 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<p>Die <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/common\/Range.java\" target=\"_blank\" rel=\"noopener\">Range<\/a>- und <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/common\/RangeSet.java\" target=\"_blank\" rel=\"noopener\">RangeSet<\/a>-Klassen findest du im <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/common\" target=\"_blank\" rel=\"noopener\">common<\/a>-Paket.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-6-java-loesung\">Advent of Code 2025 \u2013 Tag 6 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/6\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 6 Aufgabe<\/a><\/p>\n\n\n\n<p>An Tag 6 m\u00fcssen wir Zahlen aus einer Matrix auslesen und diese dann addieren oder multiplizieren \u2013 dabei m\u00fcssen wir in Teil 1 die Zahlen zweilenweise lesen und in Teil 2 spaltenweise.<\/p>\n\n\n\n<p>Teil 1 ist schnell erledigt: Wir splitten die Zeile mit dem regul\u00e4ren Ausdruck \u201e\\s+\u201c (= mindestens ein Leerzeichen):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Pattern PATTERN = Pattern.compile(<span class=\"hljs-string\">\"\\\\s+\"<\/span>);\n. . .\nString&#091;] numbers = PATTERN.split(line.strip());<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dann m\u00fcssen wir die Teilstrings nur noch in Zahlen konvertieren, diese in Listen f\u00fcr die \u201eProbleme\u201c sammeln und zuletzt alle Zahlen innerhalb dieser Listen addieren oder multiplizieren.<\/p>\n\n\n\n<p>F\u00fcr Teil 2 m\u00fcssen wir die Textdatei nicht von oben nach unten lesen, sondern von links nach rechts (oder rechts nach links \u2013 beides ist gleich gut). Innerhalb einer Spalte lesen wir eine Zahl, indem wir die Ziffern von oben nach unten lesen. Leerzeichen sehen wir einfach als Nullen an. Sobald wir in einer gesamten Spalte eine Null lesen, d. h. alle Zeilen in dieser Spalte leer waren, wissen wir, dass wir alle Spalten eines \u201eProblems\u201c gelesen haben und beginnen ab der n\u00e4chsten Spalte, die Zahlen f\u00fcr das n\u00e4chste \u201eProblem\u201c zu lesen.<\/p>\n\n\n\n<p>Die Methode <code>readNumbersInColumns(...)<\/code> zeigt, wie \u00fcber die Spalten iteriert wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">readNumbersInColumns<\/span><span class=\"hljs-params\">(List&lt;String&gt; lines, List&lt;Problem&gt; problems)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> columnCount = lines.getFirst().length();\n  <span class=\"hljs-keyword\">int<\/span> problemIndex = <span class=\"hljs-number\">0<\/span>;\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> column = <span class=\"hljs-number\">0<\/span>; column &lt; columnCount; column++) {\n    <span class=\"hljs-keyword\">long<\/span> number = readNumberInColumn(lines, column);\n    <span class=\"hljs-keyword\">if<\/span> (number != <span class=\"hljs-number\">0<\/span>) {\n      problems.get(problemIndex).addNumber(number);\n    } <span class=\"hljs-keyword\">else<\/span> { <span class=\"hljs-comment\">\/\/ separator column<\/span>\n      problemIndex++;\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Methode <code>readnumberInColumn(...)<\/code> liest eine Zahl aus einer Spalte, indem sie die Ziffern von oben nach unten liest:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">readNumberInColumn<\/span><span class=\"hljs-params\">(List&lt;String&gt; lines, <span class=\"hljs-keyword\">int<\/span> column)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">long<\/span> number = <span class=\"hljs-number\">0<\/span>;\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> row = <span class=\"hljs-number\">0<\/span>; row &lt; lines.size() - <span class=\"hljs-number\">1<\/span>; row++) {\n    <span class=\"hljs-keyword\">char<\/span> digit = lines.get(row).charAt(column);\n    <span class=\"hljs-keyword\">if<\/span> (digit != <span class=\"hljs-string\">' '<\/span>) {\n      number = number * <span class=\"hljs-number\">10<\/span> + (digit - <span class=\"hljs-string\">'0'<\/span>);\n    }\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> number;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die vollst\u00e4ndige L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day6\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 6 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-7-java-loesung\">Advent of Code 2025 \u2013 Tag 7 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/7\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 7 Aufgabe<\/a><\/p>\n\n\n\n<p>Teil 1 ist schnell gel\u00f6st \u2013 im Grunde m\u00fcssen wir nur die Splitter im Puzzle Input z\u00e4hlen.<\/p>\n\n\n\n<p>Eine triviale L\u00f6sung f\u00fcr Teil 2 w\u00e4re eine Rekursion, die f\u00fcr jeden Pfad, den ein Tachyon nimmt, pr\u00fcft, wie viele weitere m\u00f6gliche Pfade durch die Anlage es gibt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">solve<\/span><span class=\"hljs-params\">(List&lt;String&gt; input)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> startPosition = input.getFirst().indexOf(<span class=\"hljs-string\">'S'<\/span>);\n  <span class=\"hljs-keyword\">return<\/span> solve(input, <span class=\"hljs-number\">2<\/span>, startPosition);\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">long<\/span> <span class=\"hljs-title\">solve<\/span><span class=\"hljs-params\">(List&lt;String&gt; input, <span class=\"hljs-keyword\">int<\/span> row, <span class=\"hljs-keyword\">int<\/span> col)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">if<\/span> (row + <span class=\"hljs-number\">2<\/span> &gt; input.size()) {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">1<\/span>;\n  }\n  <span class=\"hljs-keyword\">if<\/span> (input.get(row).charAt(col) == <span class=\"hljs-string\">'^'<\/span>) {\n    <span class=\"hljs-keyword\">return<\/span> solve(input, row + <span class=\"hljs-number\">2<\/span>, col - <span class=\"hljs-number\">1<\/span>) + solve(input, row + <span class=\"hljs-number\">2<\/span>, col + <span class=\"hljs-number\">1<\/span>);\n  } <span class=\"hljs-keyword\">else<\/span> {\n    <span class=\"hljs-keyword\">return<\/span> solve(input, row + <span class=\"hljs-number\">2<\/span>, col);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dabei w\u00fcrden wir aber \u2013 \u00e4hnlich wie bei der rekursiven Berechnung der <a href=\"https:\/\/de.wikipedia.org\/wiki\/Fibonacci-Folge\" target=\"_blank\" rel=\"noopener\">Fibonacci-Funktion<\/a> \u2013 die weiteren Pfade von zahlreichen Positionen aus (zu denen wir auf unterschiedlichen Wegen gelangt sind) mehrfach berechnen. Die <a href=\"https:\/\/www.happycoders.eu\/de\/algorithmen\/o-notation-zeitkomplexitaet\/\">Zeitkomplexit\u00e4t<\/a> w\u00e4re exponentiell!<\/p>\n\n\n\n<p>Wesentlich einfacher ist es, die Anzahl der Timelines, auf der ein Punkt erreicht werden kann, auf der Karte zu speichern, und dabei zusammentreffende Timelines zu addieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\"> .  .  .  .  .  .  .  1  .  .  .  .  .  .  .\n .  .  .  .  .  .  1  ^  1  .  .  .  .  .  .\n .  .  .  .  .  .  1  .  1  .  .  .  .  .  .\n .  .  .  .  .  1  ^  2  ^  1  .  .  .  .  .\n .  .  .  .  .  1  .  2  .  1  .  .  .  .  .\n .  .  .  .  1  ^  3  ^  3  ^  1  .  .  .  .\n .  .  .  .  1  .  3  .  3  .  1  .  .  .  .\n .  .  .  1  ^  4  ^  3  3  1  ^  1  .  .  .\n .  .  .  1  .  4  .  3  3  1  .  1  .  .  .\n .  .  1  ^  5  ^  4  3  4  ^  2  ^  1  .  .\n .  .  1  .  5  .  4  3  4  .  2  .  1  .  .\n .  1  ^  1  5  4  ^  7  4  .  2  1  ^  1  .\n .  1  .  1  5  4  .  7  4  .  2  1  .  1  .\n 1  ^  2  ^ 10  ^ 11  ^ 11  ^  2  1  1  ^  1\n 1  .  2  . 10  . 11  . 11  .  2  1  1  .  1<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dann m\u00fcssen wir am Ende nur noch die Zahlen der letzten Reihe aufaddieren, um die gesamte Anzahl an Timelines zu erhalten.<\/p>\n\n\n\n<p>Meine L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day7\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 7 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-8-java-loesung\">Advent of Code 2025 \u2013 Tag 8 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/8\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 8 Aufgabe<\/a><\/p>\n\n\n\n<p>An Tag 8 haben wir zwei grundlegende Herausforderungen zu l\u00f6sen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wir m\u00fcssen in jeder Iteration ein noch nicht genutztes Paar von Anschlussdosen mit der k\u00fcrzesten Entfernung zueinander finden.<\/li>\n\n\n\n<li>Wir m\u00fcssen Paare von Anschlussdosen zu Schaltkreisen zusammenf\u00fcgen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"herausforderung-1-verbleibendes-paar-mit-der-kuerzesten-entfernung-finden\">Herausforderung 1: Verbleibendes Paar mit der k\u00fcrzesten Entfernung finden<\/h3>\n\n\n\n<p>Ein trivialer Ansatz ist es, die bereits genutzten Paare in einem <code>Set<\/code> zu speichern und in jeder Iteration f\u00fcr alle verbleibenden Paare die Entfernung zueinander zu berechnen und dabei das Paar mit der k\u00fcrzesten Entfernung zu bestimmen. Die Zeitkomplexit\u00e4t pro Iteration ist <em>O(n\u00b2)<\/em> \u2013 bei <em>m<\/em> Iterationen ist das <em>O(m * n\u00b2)<\/em>.<\/p>\n\n\n\n<p>Ein etwas besserer Ansatz ist es, vorab die Entfernungen aller m\u00f6glichen Paare zu berechnen und in einer Distanz-Matrix zu speichern \u2013 und dann in jeder Iteration ohne erneute Berechnung der Entfernung das Paar mit der k\u00fcrzesten Entfernung zu bestimmen. Das w\u00e4re zwar deutlich schneller, aber die Zeitkomplexit\u00e4t bleibt unver\u00e4ndert \u2013 <em>O(m * n\u00b2)<\/em>.<\/p>\n\n\n\n<p>Der beste Ansatz ist es, vorab die Paare nach ihrer Entfernung zu sortieren \u2013 dann m\u00fcssen wir im weiteren Verlauf lediglich \u00fcber die Liste der sortierten Paare iterieren. Die Zeitkomplexit\u00e4t ist nur noch <em>O(n\u00b2 + m)<\/em>.<\/p>\n\n\n\n<p>Im Code habe ich daf\u00fcr einen Record angelegt, der ein Paar von Anschlussdosen (in Form von <code>Point3D<\/code>-Objekten) und deren Entfernung zueinander speichert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\">record <span class=\"hljs-title\">Point3DPairWithDistance<\/span><span class=\"hljs-params\">(Point3D first, Point3D second, <span class=\"hljs-keyword\">double<\/span> distance)<\/span> <\/span>{}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der folgende Code wandelt eine Liste von <code>Point3D<\/code>-Objekten in eine Liste dieser Records um:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;Point3DPairWithDistance&gt; <span class=\"hljs-title\">computePairsWithDistance<\/span><span class=\"hljs-params\">(\n    List&lt;Point3D&gt; points)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> numberOfPoints = points.size();\n  List&lt;Point3DPairWithDistance&gt; pairs = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; numberOfPoints; i++) {\n    Point3D first = points.get(i);\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> j = i + <span class=\"hljs-number\">1<\/span>; j &lt; numberOfPoints; j++) {\n      Point3D second = points.get(j);\n      pairs.add(<span class=\"hljs-keyword\">new<\/span> Point3DPairWithDistance(first, second, first.distanceTo(second)));\n    }\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> pairs;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und dann muss diese Liste nur noch sortiert werden:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">pairs.sort(Comparator.comparing(Point3DPairWithDistance::distance));<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"herausforderung-2-anschlussdosen-zu-schaltkreisen-zusammenfuegen\">Herausforderung 2: Anschlussdosen zu Schaltkreisen zusammenf\u00fcgen<\/h3>\n\n\n\n<p>Um die Anschlussdosen zu Schaltkreisen zusammenzuf\u00fcgen, lege ich eine Klasse <code>CircuitSet<\/code> an. Diese speichert eine Liste von Schaltkreisen, wobei ein Schaltkreis ein <code>Set<\/code> von Dosen ist, und eine Dose wiederum durch ein <code>Point3D<\/code>-Objekt dargestellt wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> List&lt;Set&lt;Point3D&gt;&gt; circuits = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Dem Konstruktor \u00fcbergebe ich alle Dosen, und dieser legt zun\u00e4chst f\u00fcr jede einzelne Dose einen Schaltkreis an:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">CircuitSet(List&lt;Point3D&gt; points) {\n  <span class=\"hljs-keyword\">for<\/span> (Point3D point : points) {\n    Set&lt;Point3D&gt; circuit = <span class=\"hljs-keyword\">new<\/span> HashSet&lt;&gt;();\n    circuit.add(point);\n    circuits.add(newCircuit);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Um nun ein Paar von Dosen hinzuzuf\u00fcgen, suche ich zun\u00e4chst, in welchen Schaltkreisen die Dosen enthalten sind. Sind diese im gleichen Schaltkreis, ist keine weitere Aktion erforderlich. Sind sie in unterschiedlichen Schaltkreisen, merge ich Schaltkreis A in Schaltkreis B und entferne dann Schaltkreis A:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-31\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">add<\/span><span class=\"hljs-params\">(Point3DPairWithDistance pair)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> firstIndex = -<span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-keyword\">int<\/span> secondIndex = -<span class=\"hljs-number\">1<\/span>;\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; circuits.size(); i++) {\n    Set&lt;Point3D&gt; circuit = circuits.get(i);\n    <span class=\"hljs-keyword\">if<\/span> (circuit.contains(pair.first())) {\n      firstIndex = i;\n    }\n    <span class=\"hljs-keyword\">if<\/span> (circuit.contains(pair.second())) {\n      secondIndex = i;\n    }\n  }\n\n  <span class=\"hljs-comment\">\/\/ Connect circuits if both are in different ones<\/span>\n  <span class=\"hljs-keyword\">if<\/span> (firstIndex != secondIndex) {\n    circuits.get(firstIndex).addAll(circuits.get(secondIndex));\n    circuits.remove(secondIndex);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-31\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die vollst\u00e4ndige L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day8\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 8 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-9-java-loesung\">Advent of Code 2025 \u2013 Tag 9 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/9\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 9 Aufgabe<\/a><\/p>\n\n\n\n<p>An Tag 9 war Teil 1 einmal wieder schnell durch einen Brute-Force-Ansatz erledigt: einfach f\u00fcr alle m\u00f6glichen Kombinationen aus zwei roten Fliesen die Fl\u00e4che berechnen und davon die Gr\u00f6\u00dfe bestimmen.<\/p>\n\n\n\n<p>An Teil 2 musste ich l\u00e4nger knobeln \u2013 und hier wird es sicher zahlreiche unterschiedliche L\u00f6sungen geben.<\/p>\n\n\n\n<p>Zun\u00e4chst habe ich eine zweidimensionales Matrix angelegt, dort alle Kanten \u201eeingezeichnet\u201c und dann den Bereich <em>au\u00dferhalb<\/em> der Kanten mit <a href=\"https:\/\/de.wikipedia.org\/wiki\/Floodfill\" target=\"_blank\" rel=\"noopener\">Floodfill<\/a> gef\u00fcllt. Warum au\u00dferhalb? Das war einfacher als innerhalb, da ich dazu blo\u00df noch einen fliesenbreiten Rand um die Matrix legen musste und dann an Position (0, 0) mit dem F\u00fcllen beginnen konnte.<\/p>\n\n\n\n<p>Danach habe ich wieder mit dem Brute-Force-Ansatz f\u00fcr alle m\u00f6glichen Kombinationen aus zwei roten Fliesen gepr\u00fcft, ob sich eine Fliese des dadurch aufgespannten Rechtecks in dem mit Floodfill gef\u00fcllten Bereich (also au\u00dferhalb der roten und gr\u00fcnen Fliesen) befindet \u2013 und dann von allen Rechtecken, f\u00fcr die das <em>nicht<\/em> der Fall war, das gr\u00f6\u00dfte ausgew\u00e4hlt.<\/p>\n\n\n\n<p>Mit den Beispiel-Daten hat das auch gut funktioniert \u2013 beim echten Puzzle Input stie\u00df dieser Algorithmus allerdings an seine Grenzen, denn die Matrix wird dabei knapp 100.000 x 100.000, also zehn Milliarden Fliesen gro\u00df. Das Zeichnen des Randes ging noch einigerma\u00dfen schnell,  aber Floodfill war einige Minuten besch\u00e4ftigt.<\/p>\n\n\n\n<p>Ich habe lange \u00fcber einen komplett anderen, mathematischeren Algorithmus nachgedacht \u2013 bin dann aber letztlich auf die Idee gekommen, die Koordinaten zu \u201ekomprimieren\u201c. Denn von den 100.000 x 100.000 m\u00f6glichen X- und Y-Koordinaten k\u00f6nnen bei 496 roten Fliesen ja auch maximal jeweils 496 unterschiedliche genutzt sein \u2013 bzw. sogar nur 248, denn jeweils zwei Fliesen befinden sich ja an denselben X-Koordinaten, und jeweils zwei Fliesen befinden sich an denselben Y-Koordinaten.<\/p>\n\n\n\n<p>Ich habe dazu alle verwendeten X- und Y-Koordinaten gesammelt, sortiert, und dann aus allen Positionen komprimierte Positionen gemacht, indem ich zus\u00e4tzlich zu den tats\u00e4chlichen Koordinaten auch die Indizes der X- und Y-Koordinaten in der jeweiligen sortierten Koordinatenliste gespeichert habe.<\/p>\n\n\n\n<p>So sieht eine kom[primierte Position aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-32\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\">record <span class=\"hljs-title\">CompressedPosition<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> row, <span class=\"hljs-keyword\">int<\/span> col, <span class=\"hljs-keyword\">int<\/span> compressedRow, <span class=\"hljs-keyword\">int<\/span> compressedCol)<\/span> <\/span>{}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-32\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und so der \u201eKompressionsalgorithmus\u201c:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-33\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">static<\/span> List&lt;CompressedPosition&gt; <span class=\"hljs-title\">compress<\/span><span class=\"hljs-params\">(List&lt;Position&gt; positions)<\/span> <\/span>{\n  Set&lt;Integer&gt; rows = <span class=\"hljs-keyword\">new<\/span> HashSet&lt;&gt;();\n  Set&lt;Integer&gt; cols = <span class=\"hljs-keyword\">new<\/span> HashSet&lt;&gt;();\n  <span class=\"hljs-keyword\">for<\/span> (Position position : positions) {\n    rows.add(position.row());\n    cols.add(position.col());\n  }\n\n  Map&lt;Integer, Integer&gt; rowIndices = getIndexMap(rows);\n  Map&lt;Integer, Integer&gt; colIndices = getIndexMap(cols);\n\n  <span class=\"hljs-keyword\">return<\/span> positions.stream()\n      .map(position -&gt; <span class=\"hljs-keyword\">new<\/span> CompressedPosition(\n          position.row(), position.col(),\n          rowIndices.get(position.row()), colIndices.get(position.col())))\n      .toList();\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> Map&lt;Integer, Integer&gt; <span class=\"hljs-title\">getIndexMap<\/span><span class=\"hljs-params\">(Set&lt;Integer&gt; cols)<\/span> <\/span>{\n  List&lt;Integer&gt; sorted = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;(cols);\n  Collections.sort(sorted);\n\n  Map&lt;Integer, Integer&gt; indexMap = <span class=\"hljs-keyword\">new<\/span> HashMap&lt;&gt;();\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; sorted.size(); i++) {\n    indexMap.put(sorted.get(i), i);\n  }\n\n  <span class=\"hljs-keyword\">return<\/span> indexMap;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-33\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Danach konnte ich den gesamten Algorithmus einfach auf den komprimierten Koordinaten ausf\u00fchren (Gr\u00f6\u00dfe: 248 x 248) und musste lediglich f\u00fcr die Berechnung der Gr\u00f6\u00dfe eines Rechtecks auf die unkomprimierten Koordinaten zur\u00fcckgreifen.<\/p>\n\n\n\n<p>Der Brute-Force-Ansatz des Pr\u00fcfens aller m\u00f6glichen Kombinationen zweier roter Fliesen sowie der Brute-Force-Ansatz des Pr\u00fcfens, ob ein Rechteck eine Fliese au\u00dferhalb des rot-gr\u00fcnen-Bereichs umfasst, stellt offenbar kein Problem dar, denn die L\u00f6sung von Teil 2 dauert so weniger als 100 ms.<\/p>\n\n\n\n<p>Hier findest du meine vollst\u00e4ndige L\u00f6sung: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day9\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 9 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<p>Die Komprimierung findest du in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day9\/PositionsCompressor.java\" target=\"_blank\" rel=\"noopener\"><em>PositionsCompressor<\/em><\/a>, das Zeichnen des Randes und den FloodFill-Algorithmus in <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day9\/TileFloor.java\" target=\"_blank\" rel=\"noopener\"><em>TileFloor<\/em><\/a> und das Berechnen der Fl\u00e4chen und die Bestimmung der gr\u00f6\u00dften Fl\u00e4che in <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day9\/MovieTheater.java\" target=\"_blank\" rel=\"noopener\"><em>MovieTheater<\/em><\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-10-java-loesung\">Advent of Code 2025 \u2013 Tag 10 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/10\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 10 Aufgabe<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"teil-1\">Teil 1<\/h3>\n\n\n\n<p>Am zehnten Tag ist Teil 1 schnell gel\u00f6st, sobald man sich einer Sache bewusst wird: <\/p>\n\n\n\n<p>Jeder Schalter muss maximal ein Mal gedr\u00fcckt werden \u2013 denn ein zweites Mal macht die \u00c4nderung wieder r\u00fcckg\u00e4ngig. Drei Mal dr\u00fccken f\u00fchrt zum gleichen Ergebnis wie ein Mal dr\u00fccken, usw.<\/p>\n\n\n\n<p>Die maximale Anzahl Button-Konfigurationen im Puzzle Input ist 13. Damit kommen wir auf maximal 2<sup>13<\/sup>-1, also 8.191 m\u00f6gliche Kombinationen, die Buttons zu dr\u00fccken. Somit sind der eingesetzte Algorithmus und die Art und Weise, wie wir den Zustand der Lichter und die Button-Konfigurationen speichern, ziemlich egal. <\/p>\n\n\n\n<p>Ich habe eine Breitensuche implementiert, und den Status der Lichter und die Button-Konfigurationen habe ich als Bitset in einem <code>int<\/code> gespeichert. Damit reduziert sich die Berechnung eines Schaltvorgangs auf eine einzige XOR-Operation:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-34\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\">record <span class=\"hljs-title\">Lights<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> bits)<\/span> <\/span>{\n  . . .\n\n  <span class=\"hljs-function\">Lights <span class=\"hljs-title\">toggle<\/span><span class=\"hljs-params\">(ButtonWiring buttonWiring)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">new<\/span> Lights(bits ^ buttonWiring.bits());\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-34\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In der Queue f\u00fcr die Breitensuche speichere ich <code>ComputationState<\/code>-Objekte, die wie folgt aussehen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-35\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> record <span class=\"hljs-title\">ComputationState<\/span><span class=\"hljs-params\">(Lights lights, <span class=\"hljs-keyword\">int<\/span> buttonIndex, <span class=\"hljs-keyword\">int<\/span> depth)<\/span> <\/span>{}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-35\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Ein <code>ComputationState<\/code>-Objekt enth\u00e4lt den Zustand der Lichter, den Index des n\u00e4chsten Buttons (wir probieren in jedem Zustand alle Buttons rechts des zuletzt gedr\u00fcckten Buttons aus) und die aktuelle Suchtiefe. Die Breitensuche ist dann in rund einem Dutzend Zeilen Code implementiert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-36\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">solvePart1<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n  Queue&lt;ComputationState&gt; queue = <span class=\"hljs-keyword\">new<\/span> ArrayDeque&lt;&gt;();\n  queue.add(<span class=\"hljs-keyword\">new<\/span> ComputationState(<span class=\"hljs-keyword\">new<\/span> Lights(), <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">0<\/span>));\n\n  <span class=\"hljs-keyword\">while<\/span> (!queue.isEmpty()) {\n    ComputationState state = queue.remove();\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = state.buttonIndex(); i &lt; buttonWirings.size(); i++) {\n      Lights lights = state.lights().toggle(buttonWirings.get(i));\n      <span class=\"hljs-keyword\">if<\/span> (lights.equals(lightsGoal)) {\n        <span class=\"hljs-keyword\">return<\/span> state.depth() + <span class=\"hljs-number\">1<\/span>;\n      } <span class=\"hljs-keyword\">else<\/span> {\n        queue.add(<span class=\"hljs-keyword\">new<\/span> ComputationState(lights, i + <span class=\"hljs-number\">1<\/span>, state.depth() + <span class=\"hljs-number\">1<\/span>));\n      }\n    }\n  }\n\n  <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalStateException(<span class=\"hljs-string\">\"No solution found\"<\/span>);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-36\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"teil-2\">Teil 2<\/h3>\n\n\n\n<p>F\u00fcr Teil 2 habe ich mehrere Stunden mit verschiednen Brute-Force-Ans\u00e4tzen experimentiert, bin dann aber zu dem Schluss gekommen, dass das Problem daf\u00fcr zu gro\u00df ist \u2013 selbst mit den smartesten Abbruchbedingungen.<\/p>\n\n\n\n<p>Das Problem muss stattdessen mathematisch angegangen werden! Wenn wir die Button-Konfigurationen als Vektoren von Nullen und Eisen darstellen (<em>b<sub>i<\/sub><\/em>),  und den Zielzustand als Vektor von Joltage-Leveln (<em>j<\/em>), dann k\u00f6nnen wir folgende Gleichung aufstellen, wobei <em>x<sub>i<\/sub><\/em> die H\u00e4ufigkeiten sind, mit der die jeweiligen Buttons gedr\u00fcckt werden m\u00fcssen:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_400\"><img decoding=\"async\" width=\"400\" height=\"40\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-400x40.png\" alt=\"aoc2025 day10 formular\" class=\"wp-image-54217\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-400x40.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-224x22.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-336x34.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-504x50.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-672x67.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular-600x60.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/aoc2025-day10-formular.png 800w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure>\n<\/div>\n\n\n<p>Dann m\u00fcssen wir \u201enur noch\u201c diejenige L\u00f6sung dieser Gleichung finden, bei der die Summe <em>x<sub>1<\/sub> + x<sub>2<\/sub> + ... + x<sub>n<\/sub><\/em> am kleinsten ist.<\/p>\n\n\n\n<p>L\u00f6sen k\u00f6nnen wir diese Gleichung mit dem <a href=\"https:\/\/de.wikipedia.org\/wiki\/Gau%C3%9Fsches_Eliminationsverfahren\" target=\"_blank\" rel=\"noopener\">Gau\u00dfsches Eliminationsverfahren<\/a>. Ich habe in 280 Zeilen Java-Code \u2013 und unter Verwendung von <a href=\"https:\/\/www.happycoders.eu\/de\/java\/java-26-features\/#primitive-types-in-patterns-instanceof-and-switch-fourth-preview-jep-530\"><em>Primitive Types in instanceof<\/em><\/a> \u2013 eine vereinfachte Variante davon implementiert, die mit maximal drei unbekannten Variablen umgehen kann. Du findest diese Implementierung in der Klasse <em><a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day10\/GaussianElimination.java\" target=\"_blank\" rel=\"noopener\">GaussianElimination<\/a><\/em>.<\/p>\n\n\n\n<p>Die vollst\u00e4ndige L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day10\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 10 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-11-java-loesung\">Advent of Code 2025 \u2013 Tag 11 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/11\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 11 Aufgabe<\/a><\/p>\n\n\n\n<p>An Tag 11 m\u00fcssen wir einen gerichteten azyklischen Graph aufbauen und darin die Anzahl der m\u00f6glichen Pfade zwischen zwei Punkten finden. In Teil 2 kommt erschwerend hinzu, dass die Pfade durch zwei weitere Punkte gehen m\u00fcssen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"teil-1\">Teil 1<\/h3>\n\n\n\n<p>Teil 1 l\u00e4sst sich mit einer Tiefensuche l\u00f6sen und einem Cache, in dem wir f\u00fcr diejenigen Knotenpunkte, die wir vollst\u00e4ndig abgearbeitet haben, speichern, auf wie vielen Pfaden wir von dort das Ziel erreicht haben. Sobald wir einen Kontenpunkt erreichen, der in diesem Cache liegt, brauchen wir die Wege von dort nicht noch einmal zu \u00fcberpr\u00fcfen.<\/p>\n\n\n\n<p>Dieser \u201eCache\u201c ist zun\u00e4chst einfach nur ein Feld <code>pathsFoundFromHere<\/code> in den Knoten-Objekten, welches zu Beginn <code>null<\/code> ist und dann w\u00e4hrend der Rekursion nach und nach gesetzt wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-37\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Device<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String name;\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String&#091;] outputNames;\n\n  <span class=\"hljs-keyword\">private<\/span> Integer pathsFoundFromHere;\n\n  . . .\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-37\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Am Ende der Rekursion liegt im <code>pathsFoundFromHere<\/code>-Feld des Startknotens die L\u00f6sung. Dank des Caches dauert die Suche weniger als einer Millisekunde.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"teil-2\">Teil 2<\/h3>\n\n\n\n<p>F\u00fcr Teil 2 habe ich das <code>pathsFoundFromHere<\/code>-Feld durch ein <code>visitedInfo<\/code>-Feld ersetzt, in dem ich die Anzahl der Pfade zum Ziel aufgeschl\u00fcsselt habe in:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Anzahl der Pfade, auf denen die Knoten <code>dac<\/code> und <code>fft<\/code> liegen<\/li>\n\n\n\n<li>Anzahl der Pfade, auf denen nur der Knoten <code>dac<\/code> liegt<\/li>\n\n\n\n<li>Anzahl der Pfade, auf denen nur der Knoten <code>fft<\/code> liegt<\/li>\n\n\n\n<li>Anzahl der Pfade, auf denen weder der Knoten <code>dac<\/code> noch der Knoten <code>fft<\/code> liegt<\/li>\n<\/ul>\n\n\n\n<p>So sieht die zugeh\u00f6rige Klasse <code>VistedInfo<\/code> aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-38\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">VisitedInfo<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> pathsWithBothFoundFromHere;\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> pathsWithOnlyDacFromHere;\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> pathsWithOnlyFftFromHere;\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">long<\/span> pathsWithNoneFromHere;\n\n  . . .\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-38\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Sobald ich von einem Knoten aus einen Knoten erreiche, der bereits abgearbeitete wurde, addiere ich die <code>VisitedInfo<\/code> des erreichten Knotens zur <code>VisistedInfo<\/code> des aktuellen Knotens \u2013 die Parameter <code>dac<\/code> und <code>fft<\/code> geben dabei an, ob der aktuelle Knoten <code>dac<\/code> oder <code>fft<\/code> ist:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-39\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">add<\/span><span class=\"hljs-params\">(VisitedInfo other, <span class=\"hljs-keyword\">boolean<\/span> dac, <span class=\"hljs-keyword\">boolean<\/span> fft)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">if<\/span> (dac) {\n    pathsWithBothFoundFromHere += other.pathsWithBothFoundFromHere \n                                + other.pathsWithOnlyFftFromHere;\n    pathsWithOnlyDacFromHere += other.pathsWithOnlyDacFromHere\n                              + other.pathsWithNoneFromHere;\n  } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (fft) {\n    pathsWithBothFoundFromHere += other.pathsWithBothFoundFromHere \n                                + other.pathsWithOnlyDacFromHere;\n    pathsWithOnlyFftFromHere += other.pathsWithOnlyFftFromHere \n                              + other.pathsWithNoneFromHere;\n  } <span class=\"hljs-keyword\">else<\/span> {\n    pathsWithBothFoundFromHere += other.pathsWithBothFoundFromHere;\n    pathsWithOnlyDacFromHere += other.pathsWithOnlyDacFromHere;\n    pathsWithOnlyFftFromHere += other.pathsWithOnlyFftFromHere;\n    pathsWithNoneFromHere += other.pathsWithNoneFromHere;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-39\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Abarbeitung des gesamten Graphen dauert so auch bei Teil 2 weniger als eine Millisekunde, und die L\u00f6sung finden wir am Ende im Feld <code>visitedInfo.pathsWithBothFoundFromHere<\/code> des Startknotens.<\/p>\n\n\n\n<p>Die vollst\u00e4ndige L\u00f6sung findest du hier: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day11\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 11 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"advent-of-code-2025-tag-12-java-loesung\">Advent of Code 2025 \u2013 Tag 12 Java-L\u00f6sung<\/h2>\n\n\n\n<p>Aufgabe: <a href=\"https:\/\/adventofcode.com\/2025\/day\/12\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 12 Aufgabe<\/a><\/p>\n\n\n\n<p>Tag 12 habe ich zun\u00e4chst mit einer Tiefensuche implementiert: Ich lege jedes Geschenk nach und nach in allen m\u00f6glichen Rotationen und Spiegelungen unter den Baum \u2013 solange, bis alle Geschenke entweder passen ... oder nicht.<\/p>\n\n\n\n<p>F\u00fcr die Beispieldaten funktioniert das noch \u2013 f\u00fcr den eigentlichen Puzzle Input aber nicht mehr, da die Anzahl an m\u00f6glichen Kombinationen astronomisch hoch sind.<\/p>\n\n\n\n<p>Die Suche nach m\u00f6glichen vorzeitigen Abbruchbedingungen f\u00fchrte dieses Mal zum Gl\u00fcck schnell zu einem Ergebnis: Wenn man die Anzahl der Pixel aller zu platzierenden Geschenke mit der Anzahl der freien Pixel unter dem Baum vergleicht, f\u00e4llt auf, dass unter 546 der 1.000 Weihnachtsb\u00e4ume gar nicht genug Platz f\u00fcr alle Geschenke sein kann \u2013 egal wie man sie anordnet:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-40\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">int<\/span> pixelsAvailable = width * height;\n<span class=\"hljs-keyword\">int<\/span> pixelsRequired = <span class=\"hljs-number\">0<\/span>;\n\nList&lt;Present&gt; presentsToFit = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> presentIndex = <span class=\"hljs-number\">0<\/span>; presentIndex &lt; presentCounts.length; presentIndex++) {\n  <span class=\"hljs-keyword\">int<\/span> presentCount = presentCounts&#091;presentIndex];\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; presentCount; i++) {\n    Present present = presents.get(presentIndex);\n    presentsToFit.add(present);\n    Shape shape = present.shapeRotations().getFirst();\n    pixelsRequired += shape.pixelCount();\n  }\n}\n\n<span class=\"hljs-keyword\">if<\/span> (pixelsRequired &gt; pixelsAvailable) {\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-40\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>F\u00fcr die restlichen 454 Weihnachtsb\u00e4ume findet die Tiefensuche in wenigen Millisekunden eine L\u00f6sung. Das machte mich etwas stutzig.<\/p>\n\n\n\n<p>Ich habe dann noch eine zweite Abbruchbedingung eingebaut: Wenn der Platz unter dem Baum in drei mal drei Pixel gro\u00dfe Raster eingeteilt wird und wir jedes Geschenk in ein solches Feld legen, ohne dessen Muster zu betrachten \u2013 passen dann alle Geschenke? <\/p>\n\n\n\n<p>Im Code sind das wenige Zeilen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-41\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">int<\/span> numberOfPresentsThatWouldFitRegardlessOfTheirShape = (width \/ <span class=\"hljs-number\">3<\/span>) * (height \/ <span class=\"hljs-number\">3<\/span>);\n<span class=\"hljs-keyword\">if<\/span> (presentsToFit.size() &lt;= numberOfPresentsThatWouldFitRegardlessOfTheirShape) {\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-41\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und tats\u00e4chlich ist das der Fall f\u00fcr alle verbleibenden 546 Weihnachtsb\u00e4ume. <\/p>\n\n\n\n<p>Die Tiefensuche brauchen wir also gar nicht, um die L\u00f6sung zu berechnen. Ich habe sie trotzdem im Code gelassen, um die Beispielaufgabe zu l\u00f6sen. Du findest sie in der Klasse <em><a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/blob\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day12\/Tree.java\" target=\"_blank\" rel=\"noopener\">Tree<\/a><\/em>.<\/p>\n\n\n\n<p>Hier findest du meine vollst\u00e4ndige Implementierung: <a href=\"https:\/\/github.com\/SvenWoltmann\/advent-of-code-2025\/tree\/main\/src\/main\/java\/eu\/happycoders\/adventofcode2025\/day12\" target=\"_blank\" rel=\"noopener\">Advent of Code 2025 \u2013 Tag 12 Java-L\u00f6sung<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"das-ende\">Das Ende<\/h2>\n\n\n\n<p>Und damit ist <em>Advent of Code 2025<\/em> auch schon zu Ende gegangen. In diesem Jahr dauerte <em>Advent of Code<\/em> nur 12 Tage statt der \u00fcblichen 24. Der Entwickler erkl\u00e4rt <a href=\"https:\/\/adventofcode.com\/2025\/about#faq_num_days\" target=\"_blank\" rel=\"noopener\">hier<\/a>, dass ihm der Aufwand, 24 R\u00e4tsel zu erstellen, einfach zu hoch geworden sei.<\/p>\n\n\n\n<p>Ich muss zugeben, ich bin ebenfalls erleichtert, denn auch das L\u00f6sen der Aufgaben kostet viel Zeit. Zw\u00f6lf Aufgaben sind f\u00fcr meinen Geschmack vollkommen ausreichend. Und so werde ich vielleicht auch regelm\u00e4\u00dfiger teilnehmen \u2013 ich freue mich jetzt schon auf 2026!<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>M\u00f6chtest du auf dem Laufenden bleiben und informiert werden, wenn neue Artikel auf HappyCoders.eu ver\u00f6ffentlicht werden? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Verst\u00e4ndlich erkl\u00e4rte Advent of Code 2025 L\u00f6sungen in Java\u00a025 mit Fokus auf Code-Qualit\u00e4t und klarer Umsetzung.<\/p>\n","protected":false},"author":1,"featured_media":54133,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"","_seopress_titles_desc":"Verst\u00e4ndlich erkl\u00e4rte Advent of Code 2025 L\u00f6sungen in Java\u00a025 mit Fokus auf Code-Qualit\u00e4t und klarer Umsetzung.","_seopress_robots_index":"","_uag_custom_page_level_css":"","_metis_text_type":"standard","_metis_text_length":33173,"_post_count":0,"footnotes":""},"categories":[127],"tags":[208],"class_list":["post-54130","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algorithmen","tag-advent-of-code-de"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",1770,946,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",150,80,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",300,160,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",768,410,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",1024,547,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-224x120.jpg",224,120,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-336x180.jpg",336,180,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-504x269.jpg",504,269,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-672x359.jpg",672,359,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-400x214.jpg",400,214,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-600x321.jpg",600,321,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-800x428.jpg",800,428,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-944x505.jpg",944,505,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-1200x641.jpg",1200,641,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",1536,821,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2025\/12\/advent-of-code-2025-solutions.jpg",1770,946,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Verst\u00e4ndlich erkl\u00e4rte Advent of Code 2025 L\u00f6sungen in Java\u00a025 mit Fokus auf Code-Qualit\u00e4t und klarer Umsetzung.","public_identification_id":"aa8d54cebff04567ac85cec19149fcfe","private_identification_id":"a24a4112355340138e24624e4208b686","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/54130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=54130"}],"version-history":[{"count":43,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/54130\/revisions"}],"predecessor-version":[{"id":54279,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/54130\/revisions\/54279"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/54133"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=54130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=54130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=54130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}