diff --git a/aufgaben/sheet7/README.md b/aufgaben/sheet7/README.md new file mode 100755 index 0000000..5f976e9 --- /dev/null +++ b/aufgaben/sheet7/README.md @@ -0,0 +1,4 @@ +Blatt 7 +======= + +Ok, langsam wird es tatsächlich langweilig, mich zu wiederholen: Ab jetzt für jedes Aufgabenblatt einen eigenen Branch anlegen... der vom `master` abzweigt. Wehe, ihr vergesst das beim nächsten mal! :worried: diff --git a/aufgaben/sheet7/task1/README.md b/aufgaben/sheet7/task1/README.md new file mode 100755 index 0000000..2e42e9b --- /dev/null +++ b/aufgaben/sheet7/task1/README.md @@ -0,0 +1,10 @@ +Aufgabe 1: Fibonacci Iterator +============================= + +Schreibt ein Programm, welches die ersten 20 Zahlen in der [Fibonacci-Folge][fib-wiki] ausgibt. +Entwerft dazu selber einen Typ, der das Trait `Iterator` implementiert und so *theoretisch* alle Zahlen aus der Fibonacci-Folge generieren kann. +In `main()` sollen dann die ersten 20 ausgegeben werden. + + + +[fib-wiki]: https://de.wikipedia.org/wiki/Fibonacci-Folge diff --git a/aufgaben/sheet7/task2/README.md b/aufgaben/sheet7/task2/README.md new file mode 100755 index 0000000..ff56388 --- /dev/null +++ b/aufgaben/sheet7/task2/README.md @@ -0,0 +1,24 @@ +Aufgabe 2: Diverse Funktionen +============================= + +In dieser Aufgabe sollen diverse kleinere Funktionen enstehen. +In der Musterlösung habe ich immer irgendwie Iteratoren und Iterator-Methoden genutzt, also liegt es nahe, dass ihr es auch tun solltet. +Wenn ihr natürlich meint, eine schönere Lösung ohne Iteratoren gefunden zu haben, könnt ihr sie eurem Tutor natürlich auch vorstellen ;-) + +Versucht bei dieser Aufgabe alle Funktionen immer möglichst kurz (also mit wenigen Anweisungen) zu implementieren. Ihr müsst also auch nicht so sehr auf die Laufzeit eurer Algorithmen achten. + +Euch ist ein Gerüst mit diversen Unittests gegeben. Die Testfälle erklären die Funktionen zusätzlich. + +*Hinweis*: Es könnten für diese Aufgabe auch Funktionen direkt aus dem Modul `std::iter` sinnvoll sein. + +### Funktionen + +- `factorial()`: Berechnet `x!` für ein gegebenes `x`. + +- `rot13()`: "Verschlüsselt" einen gegebenen String mit der derzeit besten [Verschlüsselungsmethode Rot13](https://de.wikipedia.org/wiki/ROT13). Die einzige noch bessere Verschlüsselung ist Rot26. Falls ihr meint, dass ihr es hinbekommt, könnt ihr zusätzlich auch gerne Rot26 implementieren... + +- `is_palindrome()`: Testet ob ein gegebener String ein Palindrom ist. + +- `used_chars_count()`: Gibt die Anzahl der unterschiedlichen Zeichen im übergebenen String zurück. Whitespace-Zeichen sollen aber nicht mitgezählt werden. Ihr könnt hier auch gerne eine passende collection aus `std` benutzen... + +- `greatest_subsequencial_sum()`: Bekommt ein Array von ganzen Zahlen gegeben und sucht nun das Subarray (die Slice), bei dem die Summe aller Zahlen am größten unter allen möglichen Subarrays ist. diff --git a/aufgaben/sheet7/task2/iters.rs b/aufgaben/sheet7/task2/iters.rs new file mode 100755 index 0000000..d5408e5 --- /dev/null +++ b/aufgaben/sheet7/task2/iters.rs @@ -0,0 +1,47 @@ +#[test] +fn test_factorial() { + assert_eq!(factorial(1), 1); + assert_eq!(factorial(2), 2); + assert_eq!(factorial(3), 6); + assert_eq!(factorial(15), 1_307_674_368_000); +} + +#[test] +fn test_is_palindrome() { + assert!(is_palindrome("bob")); + assert!(is_palindrome("anna")); + assert!(is_palindrome("lagerregal")); + + assert!(!is_palindrome("peter")); +} + +#[test] +fn test_greatest_subsequencial_sum() { + let a = [1, 2, 39, 34, 20, -20, -16, 35, 0]; + assert_eq!(greatest_subsequencial_sum(&a), &a[0..5]); + + let b = [-3, -9, -8, -34]; + assert_eq!(greatest_subsequencial_sum(&b), &[]); +} + +#[test] +fn test_rot13() { + assert_eq!(rot13("hello"), "uryyb"); + assert_eq!(rot13("uryyb"), "hello"); + + assert_eq!( + rot13("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), + "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm" + ); + + assert_eq!(rot13("peter"), "crgre"); +} + +#[test] +fn test_used_letters() { + assert_eq!(used_chars_count(&["hi", "ih gitt"]), 4); + assert_eq!(used_chars_count(&["peter"]), 4); + assert_eq!(used_chars_count(&["p e t e r", "barbara"]), 6); +} + +fn main() {} diff --git a/aufgaben/sheet7/task3/README.md b/aufgaben/sheet7/task3/README.md new file mode 100755 index 0000000..ab0d474 --- /dev/null +++ b/aufgaben/sheet7/task3/README.md @@ -0,0 +1,6 @@ +Aufgabe 3: Fold +=============== + +Die Methode `Iterator::fold()` ist sehr mächtig, aber nicht trivial zu benutzen. In dieser Aufgabe sollt ihr `fold()` benutzen, um das Verhalten von `Iterator::{product(), max(), all()}` zu simulieren. Das heißt, dass euer `fold()` Aufruf genau zu dem gleichen Ergebnis wie `product()`, `max()` oder `all()` kommt. + +Ihr könnt alle drei Aufrufe einfach mit einem kleinen Beispiel in `main()` programmieren. Es sollte also irgendetwas funktionieren und ihr solltet in der Lage sein, eurem Tutor zu erklären, warum es funktioniert. diff --git a/aufgaben/sheet7/task4/README.md b/aufgaben/sheet7/task4/README.md new file mode 100755 index 0000000..dc2024f --- /dev/null +++ b/aufgaben/sheet7/task4/README.md @@ -0,0 +1,40 @@ +Aufgabe 4: Kopierbefehl +======================= + +(*In dieser Aufgabe geht es nicht mehr unbedingt nur um Iteratoren!*) + +In dieser Aufgabe sollt ihr den `cp` Befehl nachprogrammieren ... Ok, nur einen Teil davon. +Euer Programm soll zwei Dateinamen als *command line parameter* erhalten und dann von der einen Datei in die andere kopieren: + +``` +$ mycp Cargo.toml Peter.toml +``` + +Euer Programm soll also `mycp` heißen! +Wenn ihr es richtig gemacht habt, könnt ihr mit dem Befehl `cargo install` euer Programm global auf eurem System installieren (die Executable wird in `~/.cargo/bin` kopiert, welches im `$PATH` ist). Damit ihr es aber nicht immer neu installieren müsst, um es auszuprobieren, könnt ihr es aber natürlich mit `cargo run` testen. Die Kommandozeilenparameter werden nach den `--` übergeben: + +``` +$ cargo run -- Cargo.toml Peter.toml +``` + +Die Hauptschritte zur Implementation sind folgende: + +### a) Parsen der Kommandozeilenparameter + +Diese müssen zunächst eingelesen werden und auf Gültigkeit überprüft werden (richtige Anzahl?). +Dies soll in einer eigenen Funktion geschehen, in der *keine* Ausgabe auf dem Terminal geschehen soll. +Alle Informationen müssen im Rückgabewert kodiert sein. + +Hierzu ist sicherlich das [`std::env` Modul](https://doc.rust-lang.org/std/env/index.html) interessant. + + +### b) Kopieren des Dateiinhalts + +Falls die Parameter korrekt waren, muss jetzt von einer Datei in die andere kopiert werden. +Das soll ebenfalls in einer eigenen Funktion passieren, welche *keine* Ausgaben auf dem Terminal macht. + +Dabei sollten natürlich auch Fehler behandelt werden. +Das heißt aber nicht, dass ihr selber viel Code programmieren müsst; wahrscheinlich ist die Implementierung kürzer, als ihr anfangs vermuten würdet. + +Wie man schon vermutet, wird hier das [`std::io` Modul](https://doc.rust-lang.org/std/io/index.html) eine Rolle spielen. +Nur die Funktion `std::fs::copy()` dürft ihr **nicht** nutzen! Das wäre ja zu einfach ;-)