faecher:informatik:oberstufe:java:aoc:aco2023:day10:start

Tag 10 - Pipe Maze

Die heutige Aufgabe war nicht ganz einfach zu programmieren. Man musste viele Fälle einzeln durch if-else abdecken.
  • Wandle die Eingabe in ein zweidimensionales char-Array um. Speichere dieses am besten als Instanzvariable um flexibel darauf zugreifen zu können. Merke dir dabei direkt die Start-Koordinaten vom Buchstaben "S".
  • Erstelle eine Hilfsmethode die du häufiger benötigen wirst: getDirection(char from, char c). Die Methode soll uns sagen, in welcher Richtung man einen Buchstaben wieder verlässt, wenn man ihn aus einer bestimmten Richtung betritt. Du kannst dazu t, b, l, r nutzen für top, bottom, left, right. Bsp.: getDirection(t, L) gibt die Richtung r zurück. Du wirst für diese Methode zahlreiche Bedingungen überprüfen müssen. Denke auch an den Fall, dass man etwas falsches prüft - dann soll eine "Fehlerbuchstabe" zurückgegeben werden. Bsp.: getDirection(l, L) soll x zurückgeben.
  • Prüfe nun für die Startkoordinate in alle vier Richtungen, ob diese Richtungen möglich wären, oder nicht (bei zweien wirst du bei der Richtungsüberprüfung den Fehlerbuchstaben x bekommen.
  • Wiederhole nun bis du einmal im Kreis gelaufen bist und wieder bei "S" angelangt bist:
    • Je nach Richtung, in die du dich bewegst, änderst du deine x- oder y-Koordinate.
    • Lasse dir für diese neue Koordinate wieder die nächste Richtung mithilfe der oberen Methode geben.
    • Pro Schritt erhöhst du den Schrittzähler.
  • Am Ende ist das Ergebnis die Hälfte des Schrittzählers.

Lösungsvorschlag

Teil 2 ist recht knifflig und benötigt die verzwickte Überprüfung von Bedingungen.

  • Erstelle gleich zu Beginn ein weiteres boolean[][] Array, in welchem du später beim Durchlaufen des Loops alle Koordinaten auf true setzt, die dem gelaufenen Pfad entsprechen.
  • Nachdem du die Startkoordinaten von "S" gefunden hast musst du "S" durch den korrekten Character ersetzen der an diese Stelle gesetzt werden kann (L, J, F, 7, | oder -).
  • Wenn du den ganzen Loop durchlaufen hast, dann musst du beginnen, sämtliche Character nochmals zeilenweise zu betrachten.
    • Speichere dir pro Zeile in einer boolean-Variablen, ob du gerade inside oder outside bist (im geschlossenen Kreis oder außerhalb).
    • Wenn du aktuell auf einer Koordinate bist, die du im boolean-Array nicht als Pfad markiert hast, dann wird dein inside-Zähler um eins erhöht, falls deine eben erstellte boolean-Variable anzeigt, dass du inside bist. Sonst gehst du mit continue einfach zur nächsten Koordinate.
    • Andernfalls (du bist auf einem Pfad) musst je nach Character c umfangreich unterscheiden:
      • Wenn c der Pipe-Operator | ist, dann kannst du direkt die inside/outside-Variable zum jeweils anderen Wert switchen, weil du weißt, dass durch das Passieren dieses Zeichens auf jeden Fall von innen nach außen gelangt bist oder andersherum.
      • Wenn c nun L oder F ist, dann bedeutet das, dass danach eine längere Sequenz beginnt, die horizontal weiterläuft, ohne dass zwangsweise sofort ein Wechseln von innen nach außen oder andersherum stattfindet. Z. B.: L—7, LJ oder F-7. Sehr wichtig ist an dieser Stelle aber, dass du dir diesen Anfangsbuchstaben der horizontalen Sequenz (L oder F) merkst.
      • Wenn c ein horizontales Bindestrich - ist, dann kannst du einfach mit continue weitermachen.
      • Wenn c das eine mögliche Ende einer horizontalen Sequenz anzeigt (J), dann musst du unterscheiden, was das Zeichen vom Beginn der horizontalen Sequenz war.
        • Wenn die Sequenz mit L begann, dann heißt das, dass der Pfad nicht deinen Weg gekreuzt hat (z. B. L—J oder LJ) und du damit auch nicht von inside nach outside oder anders herum gewechselt hast. Du brauchst gar nichts tun (continue).
        • Wenn die Sequenz hingegen mit F begonnen hat, dann hat der Pfad deinen Weg gekreuzt (z. B. FJ oder F–J). Inside/outside muss also getauscht werden.
      • Wenn c das andere mögliche Ende einer horizontalen Sequenz anzeigt (7), dann musst du entsprechend andersherum verfahren.

Lösungsvorschlag

  • faecher/informatik/oberstufe/java/aoc/aco2023/day10/start.txt
  • Zuletzt geändert: 10.12.2023 17:41
  • von Marco Kuemmel