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

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
faecher:informatik:oberstufe:java:aoc:aco2023:day1:start [01.12.2023 17:26] Frank Schiebelfaecher:informatik:oberstufe:java:aoc:aco2023:day1:start [12.11.2024 06:25] (aktuell) Frank Schiebel
Zeile 1: Zeile 1:
 ====== Tag 1 ====== ====== Tag 1 ======
  
-Mehrere Zeilen werden eingelesen, diese bestehen aus Buchstaben und Zahlen. Man muss die erste Zahl und die letzte Zahl jeder Zeile finden. Es kann auch manchmal nur eine Zahl in der ganzen Zeile geben, dann fungiert diese sowohl als erste, als auch als letzte Zahl. Diese beiden Zahlen werden zusammengesetzt als zweistellige Zahl. Alle zweistelligen Zahlen aus jeder Zeile werden zusammenaddiert und bilden das gesuchte Ergebnis. +===== Aufgabe =====
- +
  
 +  * {{ :faecher:informatik:oberstufe:java:aoc:aco2023:day1:2023_day1.png?linkonly |Aufgabe}}
 +  *  {{ :faecher:informatik:oberstufe:java:aoc:aco2023:day1:d1input.zip |}}
 +    * Beispiele d1e1.txt, d1e2.txt
 +    * Input d2i.txt. 
  
  
 +++++ Kontrollergebnisse |
 +  * Eingabedatei d1i.txt: 
 +    * Teil 1 - ''55017''
 +    * Teil 2 - ''53539''
 +++++
  
 <tabs> <tabs>
Zeile 16: Zeile 23:
  
 === Teil 1 === === Teil 1 ===
 +
 +
 +Mehrere Zeilen werden eingelesen, diese bestehen aus Buchstaben und Zahlen. Man muss die erste Zahl und die letzte Zahl jeder Zeile finden. Es kann auch manchmal nur eine Zahl in der ganzen Zeile geben, dann fungiert diese sowohl als erste, als auch als letzte Zahl. Diese beiden Zahlen werden zusammengesetzt als zweistellige Zahl. Alle zweistelligen Zahlen aus jeder Zeile werden zusammenaddiert und bilden das gesuchte Ergebnis.
  
 ++++ Tipp 1 |  ++++ Tipp 1 | 
Zeile 157: Zeile 167:
 Prinzipielles Vorgehen, um eine Zeile zu untersuchen: Prinzipielles Vorgehen, um eine Zeile zu untersuchen:
  
-  * Wandle die Zeile in ein Array aus Zeichen um: ''line.toCharArray();'' [[1|https://www.geeksforgeeks.org/java-string-tochararray-example/]]+  * Wandle die Zeile in ein Array aus Zeichen um: ''line.toCharArray();'' (([[https://www.geeksforgeeks.org/java-string-tochararray-example/|Weitere Infos toCharArray()]])) 
 +  * Betrachte jedes Zeichen in einer ''foreach'' Schleife oder einer ''for'' Schleife. (([[https://www.geeksforgeeks.org/for-each-loop-in-java/|Weitere Infos zur ForEach-Schleife]]))(([[https://www.geeksforgeeks.org/java-for-loop-with-examples/|Weitere  Infos zur For-Schleife]])). 
 +  * Entscheide, ob das Zeichen eine Ziffer ist: ''Character.isDigit(z)'' ((Weitere Infos zu [[https://www.geeksforgeeks.org/character-isdigit-method-in-java-with-examples/|isDigit]])) 
 +  * Die erste gefundene Ziffer sind die Zehner, die letzte gefundene Ziffer sind die Einer. Mit einer Aggregationsvariablen kann man markieren, ob die 10er schon gefunden wurden. Wenn ja überschreibt man von diesem Zeitpunkt an die Einer mit der jeweils letzten gefundenen Ziffer. Sind Zehner und Einer dieselbe Ziffer, führt das hier nicht zu Problemen, weil zunächst der Marker auf "Zehner gefunden" gesetzt wird und deswegen dieselbe Ziffer als Einer gemerkt wird. Wenn in der Folge keine weitere Einerziffer gefunden wird, bleibt es dabei.  
 +  * Wenn die Zeile bearbeite hat, erhält man den Kalibrierungswert für die Zeile als ''c=zehner*10+einer''. Damit man allerdings mit den Zehnern und Einern rechnen kann, die ja vom Typ ''char'' sind, muss man sie zu einem Integer Wert umwandeln.  (([[https://www.geeksforgeeks.org/java-program-to-convert-char-to-int/|Convert Char to Int]])) 
 + 
 +Das macht man jetzt in einer Schleife für alle Zeilen und addiert dabei die Kalibrierungswerte. 
 + 
 +++++ Codegerüst |  
 + 
 +<code java> 
 +public int partOne() { 
 +        int answer=0; 
 +         
 +        // Wiederhole für jede Zeile... 
 +        for(String line: inputLines) { 
 +             
 +            // Untersuchung einer Zeile 
 +             
 +            
 +            // Erzeuge ein Array aus Zeichen 
 +            char[] zeichen = FIXME 
 +             
 +            // Marker: Wurde die erste Ziffer gefunden? 
 +            boolean ersteGefunden = false; 
 +             
 +            // Die Zahl setzt sich aus "Zehnern" und "Einern" zusammen 
 +            int zehner=0; 
 +            int einer=0; 
 + 
 +            // Jedes Zeichen untersuchen 
 +            for(char z: zeichen) { 
 +                if (FIXME) { 
 +                    zehner =  Character.getNumericValue(z);    
 +                    ersteGefunden = true; 
 +                }  
 + 
 +                if (FIXME) { 
 +                    einer =  Character.getNumericValue(z); 
 +                } 
 +            } 
 +            // Für jede Zeile das "Zeilenergebnis" zur Antwort addieren 
 +            answer = answer + 10 * zehner + einer; 
 +        } 
 +        // Zu kopieren ins Lösungsfeld ausgeben 
 +        System.out.println(answer); 
 +        return answer; 
 +    } 
 +</code> 
 +++++ 
 + 
 +=== Hinweise zu Teil 2 === 
 + 
 +In Teil 2 muss man auch noch "Zahlenwörter" wie "one" oder "two" finden, diese können sich sogar überschneiden, aber das ist eigentlich egal. 
 + 
 +Die Methode für Teil 1 hilft hier nicht direkt weiter, man kann stattdessen folgendes Vorgehen wählen:  
 + 
 +  * Den Wert für den Zehner ist stets das am weitesten links stehende Zahlwort oder die am weitesten links stehende Ziffer. Erkennen kann man die Position am Index im Array - das Element, mit dem kleinsten Indes gewinnt das Rennen als "Zehner"
 +  * Für die Einer geht man genauso vor, man such das Vorkommen eines Zahlworts oder einer Ziffer möglichst weit rechts.  
 +  * Aufpassen muss man - wie schon in Teil 1 - dass man die passenden Typen für die gewünschten Operationen verwendet und diese wenn nötig passend umwandelt. 
 + 
 +Man kann zur Vereinfachung mit folgendem Array für die Zahlenworte arbeiten: 
 + 
 +<code java> 
 +String [] werte = { 
 +                "dummy", "one", "two", "three", "four", "five",  
 +                "six", "seven", "eight", "nine" 
 +            }; 
 +</code> 
 + 
 +Der "dummy"-Eintrag sorgt für gedankliche Vereinfachung, denn dadurch ist der Index jedes Eintrags der zugehörige Zahlenwert. 
 + 
 +Um die Zehnerstelle zu finden, sucht man jedes Zahlwort und jede dazugehörige Ziffer in der zu untersuchenden Zeile. Hier hilft die Methode ''indexOf()'' der Java String-Klasse(([[https://www.geeksforgeeks.org/java-string-indexof/|weitere Infos zu indexOf]])). Die Methode liefert den Index des ersten Fundorts des Suchstrings zurück, wenn der String nicht gefunden wird -1. 
 + 
 +**Beispiel:**  
 + 
 +<code java> 
 +String zeile = "tbninefour4eight"; 
 +zeile.indexOf("nine") // liefert 2 
 +zeile.indexOf("wurstsalat") // liefert -1 
 +</code> 
 + 
 +Die Methode ''lastIndexOf()'' macht dasselbe "von rechts", sucht also den Index des letzten Vorkommens der Zeichenkette. (( Infos zu [[https://www.geeksforgeeks.org/java-lang-string-lastindexof-method/|lastIndexOf]])) 
 + 
 +Das folgende Codegerüst beinhaltet die nach dieser Logik implementierte Suche nach der Zehnerstelle - du kannst das nachvollziehen und versuchen, die Einerstelle und die Berechnung der GEsamtsumme nachzutragen. 
 + 
 +++++ Codegerüst für die Zehnerstelle | 
 +<code java> 
 +    public int partTwo() { 
 +        int answer=0; 
 + 
 +        String [] werte = { 
 +                "dummy", "one", "two", "three", "four", "five",  
 +                "six", "seven", "eight", "nine" 
 +            }; 
 + 
 +        for(String line: inputLines) { 
 + 
 +            // Suche Zehner, Positionen sind nicht vorhanden: -1 
 +            int zehnerPosition=-1; 
 +            int zehnerWert=-1; 
 +             
 +            // Jede Zahl von 1 bis 10 in der Zeile suchen,  
 +            // als Ziffer und als Zahlwort 
 +            for(int i=1; i<werte.length; i++) { 
 +                // Gibts die Ziffer in der Zeile?  
 +                // Achtung: Integer.toString(i), denn indexOf() benötigt als  
 +                // Argument einen String! 
 +                int zifferPosition = line.indexOf(Integer.toString(i)); 
 +                // Gibst das Zahlwort in der Zeile? 
 +                int wortPosition = line.indexOf(werte[i]); 
 +                 
 +                // Position merken, wenn gefunden. 
 +                // Nur die am weitesten links stehende Postion liefert  
 +                // den Zehnerwert 
 +                 
 +                // Zuerst für die Ziffer 
 +                if(zifferPosition != -1) { 
 +                    if( zehnerPosition == -1 || zifferPosition < zehnerPosition) { 
 +                        zehnerPosition = zifferPosition; 
 +                        zehnerWert = i; 
 +                    } 
 +                } 
 +                // Jetzt für das Wort 
 +                // Beide Untersuchungen setzen wenn nötig  
 +                // zehnerPosition und zehnerWert neu 
 +                if(wortPosition != -1) { 
 +                    if( zehnerPosition == -1 || wortPosition < zehnerPosition) { 
 +                        zehnerPosition = wortPosition; 
 +                        zehnerWert = i; 
 +                    } 
 +                } 
 +            } 
 +             
 +            // Suche Einer 
 +             
 +            // TODO 
 +             
 +            answer = // Rechnen! 
 +        } 
 +        return answer 
 +    } 
 +</code> 
 +++++ 
 + 
 +=== Lösungsvorschlag ===
  
 +Einen Lösungsvorschlag nach der Beschreibung Variante 2 findest du hier: https://codeberg.org/qg-info-unterricht/aoc-bluej-2023/src/branch/main/day1.java
  
 </pane> </pane>
 </tabs> </tabs>
  
  • faecher/informatik/oberstufe/java/aoc/aco2023/day1/start.1701451611.txt.gz
  • Zuletzt geändert: 01.12.2023 17:26
  • von Frank Schiebel