mirror of
https://github.com/LukasKalbertodt/programmieren-in-rust.git
synced 2025-06-29 08:17:32 +02:00
Rename sheet folders to assure proper sorting
This commit is contained in:
94
aufgaben/sheet03/task1/README.md
Executable file
94
aufgaben/sheet03/task1/README.md
Executable file
@ -0,0 +1,94 @@
|
||||
Aufgabe 3.1: Rule 90
|
||||
====================
|
||||
|
||||
Zelluläre Automaten simulieren ein System von Zellen mit diskreten Werten in
|
||||
diskreten Zeitschritten, wobei sich der Zustand des Systems zum Zeitpunkt
|
||||
*n + 1* deterministisch aus dem Zustand zum Zeitpunkt *n* berechnen lässt.
|
||||
In den meisten Fällen hängt der Wert einer Zelle allein von seinem eigenen Wert
|
||||
und den Werten seiner Nachbarn zum vorherigen Zeitpunkt ab.
|
||||
|
||||
["Rule 90"][1] ist ein eindimensionaler, zellulärer Automat, dessen Zellen
|
||||
boolesch sind, also nur zwei Werte annehmen können.
|
||||
Oft spricht man bei einer Zelle mit einer 0 von einer "toten Zelle", bei einer
|
||||
1 von einer "lebenden" Zelle.
|
||||
|
||||
Diese Zellen können nun nach bestimmten Vorschriften in diskreten Zeitschritten
|
||||
simuliert werden. Der Wert einer Zelle zu dem Zeitschritt *n + 1* hängt von
|
||||
seinem Wert und der Wert seiner beiden direkten Nachbarn zum Zeitpunkt *n* ab.
|
||||
Sind z.B. zum Zeitpunkt *n* alle drei Zellen tot, wird die mittlere der Zellen
|
||||
zum Zeitpunkt *n + 1* ebenfalls tot bleiben.
|
||||
|
||||
Die vollständigen Regeln lauten wie folgt:
|
||||
|
||||
| Vorheriger Zeitschritt | `111` | `110` | `101` | `100` | `011` | `010` | `001` | `000` |
|
||||
| ----------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- |
|
||||
| Neuer Wert für mittlere Zelle | `_0_` | `_1_` | `_0_` | `_1_` | `_1_` | `_0_` | `_1_` | `_0_` |
|
||||
|
||||
Nun kann man die diskreten Zeitschritte zeilenweise anzeigen. Das sieht dann
|
||||
z.B. so aus (in diesem Beispiel ist der Automat 5 Zellen groß):
|
||||
|
||||
```
|
||||
0 1 1 0 0
|
||||
1 1 1 1 0
|
||||
1 0 0 1 0
|
||||
0 1 1 0 0
|
||||
```
|
||||
|
||||
Zu diesem Zeitpunkt sollte man sich fragen: Was ist mit den Randzellen?
|
||||
In dieser Aufgabe gehen wir davon aus, dass der Anfang und das Ende des Systems
|
||||
verbunden sind, d.h. der linke Nachbar der ersten Zelle ist die letzte Zelle
|
||||
und der rechte Nachbar der letzten Zelle ist die erste Zelle.
|
||||
|
||||
---
|
||||
|
||||
In dieser Aufgabe sollt ihr ein Programm schreiben, welches den Automaten
|
||||
"Rule 90" für Nutzereingaben simuliert. Diese Funktionalität soll in mehrere
|
||||
Funktionen aufgeteilt werden.
|
||||
|
||||
|
||||
### a) Eingabe einlesen
|
||||
|
||||
Zunächst muss vom Nutzer die initiale Konfiguration des Automaten eingelesen
|
||||
werden.
|
||||
Dafür soll eine Funktion `read_input()` geschrieben werden, die teilweise
|
||||
bereits von uns bereitgestellt wurde.
|
||||
In dem schon existierenden Code wird lediglich ein String vom Nutzer
|
||||
eingelesen, der nur '0' und '1' enthält.
|
||||
Eure Aufgabe ist es, aus diesem String einen `Vec<bool>` zu erstellen, der für
|
||||
jede '0' im String einen `false`-Eintrag und für jede '1' einen `true`-Eintrag
|
||||
enthält (in der richtigen Reihenfolge).
|
||||
Dieser Vektor soll dann von der Funktion zurückgegeben werden.
|
||||
|
||||
|
||||
### b) Zeitschritt simulieren
|
||||
|
||||
Nun sollt ihr eine Funktion `next_step()` schreiben, die aus der Konfiguration
|
||||
des Automaten zu einem Zeitpunkt den nächsten Zeitpunkt berechnen soll.
|
||||
Den Automaten zu einem Zeitpunkt stellen wir weiterhin einfach als ein
|
||||
Boolean-Array dar; es muss also kein neuer Typ erstellt werden.
|
||||
|
||||
|
||||
### c) Funktionen in `main()` benutzen
|
||||
|
||||
Nun müssen beide Funktionen noch genutzt werden.
|
||||
In der `main()` Funktion wird eine initiale Konfiguration des Automaten
|
||||
eingelesen, welcher dann über z.B. 20 Zeitschritte simuliert werden soll.
|
||||
|
||||
In jedem Zeitschritt soll der Zustand in einer Zeile auf dem Terminal
|
||||
ausgegeben werden. Die Ausgabe kann entweder in Form von 0en und 1en geschehen
|
||||
(wie oben im Beispiel) oder ihr könnt andere eindeutige Zeichen verwenden.
|
||||
Es würde sich z.B. anbieten, für tote Zellen zwei Leerzeichen und für lebende
|
||||
Zellen zwei U+2588 FULL BLOCK ('█') auszugeben:
|
||||
|
||||
```
|
||||
████
|
||||
████████
|
||||
██ ██
|
||||
████
|
||||
```
|
||||
|
||||
Wenn alles klappt, probiert mal die initiale Konfiguration
|
||||
`0000000000000001000000000000000` aus!
|
||||
|
||||
|
||||
[1]: https://en.wikipedia.org/wiki/Rule_90
|
51
aufgaben/sheet03/task1/rule90.rs
Executable file
51
aufgaben/sheet03/task1/rule90.rs
Executable file
@ -0,0 +1,51 @@
|
||||
//! Task 3.1: Rule 90
|
||||
|
||||
fn main() {
|
||||
// TODO: Task 1c)
|
||||
}
|
||||
|
||||
/// Reads a valid initial configuration for our automaton from the terminal.
|
||||
fn read_input() -> Vec<bool> {
|
||||
// This tries to read a string from the terminal, checks whether it's
|
||||
// valid (only contains 1's and 0's). If the user fails to input a correct
|
||||
// string, this routine will ask again until the user finally manages to
|
||||
// give us a correct string.
|
||||
//
|
||||
// You don't need to understand this routine yet; that's why I've written
|
||||
// it already ;-)
|
||||
//
|
||||
// You only need to use the `input` variable (of type `String`). You can
|
||||
// also assume that it only contains '0' and '1' chars.
|
||||
let input = {
|
||||
let mut buffer = String::new();
|
||||
|
||||
loop {
|
||||
println!("Please give me the initial configuration (a string of '0' and '1'!):");
|
||||
buffer.clear();
|
||||
|
||||
// `read_line` returns an error if the input isn't valid UTF8 or if
|
||||
// a strange IO error occured. We just panic in that case...
|
||||
std::io::stdin()
|
||||
.read_line(&mut buffer)
|
||||
.expect("something went seriously wrong :O");
|
||||
|
||||
if buffer.trim().chars().all(|c| c == '1' || c == '0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.trim().to_string()
|
||||
};
|
||||
|
||||
// TODO: Task 1a)
|
||||
}
|
||||
|
||||
// TODO: Task 1b)
|
||||
|
||||
#[test]
|
||||
fn rule90_rules() {
|
||||
assert_eq!(next_step(&[false, false, false]), vec![false, false, false]);
|
||||
assert_eq!(next_step(&[ true, false, false]), vec![false, true, true]);
|
||||
assert_eq!(next_step(&[ true, true, false]), vec![ true, true, false]);
|
||||
assert_eq!(next_step(&[ true, true, true]), vec![false, false, false]);
|
||||
}
|
Reference in New Issue
Block a user