final commit

This commit is contained in:
2021-11-29 21:24:18 +01:00
parent c2ca8aa9fc
commit c0c29134c8
8 changed files with 261 additions and 548 deletions

View File

@ -3,34 +3,38 @@
## Lösungsidee
Für jede normale Textdatei wird ASCII encoding verwendet bzw. ein Encoding
Standart welcher auf ASCII basiert und zusätzliche Sonderzeichen enthält,
wobei die Werte die bereits in ASCII enthalten übernommen wurden.
Die ASCII codes für die Buchstaben sind entsprechend des Alphabets
Standard, welcher auf ASCII basiert und zusätzliche Sonderzeichen enthält,
wobei die Werte, die bereits in ASCII enthalten sind, übernommen wurden.
Die ASCII Codes für die Buchstaben sind entsprechend des Alphabets
hintereinander angeordnet. Dies ist sehr nützlich, da somit eine Liste der
Buchstaben und deren Position im Alphabet nicht benötigt wird.<br>
Zur Lösung des Parkplatzproblems werden die Autos wenn möglich nach links bzw.
rechts verschoben bis die Parklücke frei ist. Je nachdem in welche Richtung
Buchstaben und deren Position im Alphabet nicht benötigt wird.
Zur Lösung des Parkplatzproblems werden die Autos, wenn möglich nach links bzw.
rechts verschoben, bis die Parklücke frei ist. Je nachdem, in welche Richtung
weniger Autos verschoben werden müssen, wird die Verschiebungsrichtung gewählt.
## Umsetzung
Da die Lösung des Problem keine besondere Library benötigt wird und die Anforderungen
an die Ausführungsgeschwindigkeit gering sind, hätte man fast jede Progmiersprache
wählen können. Ich habe mich für Go entschieden.<br>
Das Programm akzeptiert als Argumente eine beliebige Anzahl an Pfaden zu Parkplatzdatein.
Da die Lösung des Problems keine besondere Library benötigt und die Anforderungen
an die Ausführungsgeschwindigkeit gering sind, hätte man fast jede Programmiersprache
wählen können. Ich habe mich für Go entschieden.
Das Programm akzeptiert als Argumente eine beliebige Anzahl an Pfaden zu Parkplatzdateien.
Für das Iterieren über die Argumente wird eine for-Schleife benutzt.
Innerhalb der Schleife wird die Eingabedatei ausgelesen. Anhand des ersten und letzten
Buchstaben der Autos auf den normalen Parkplätzen wird die die Anzahl an Parkplätzen
Buchstabens der Autos auf den normalen Parkplätzen wird die Anzahl an Parkplätzen
bestimmt. Anschließend wird eine Slice (ein dynamisch vergrößerbares Array in Go)
mit den Buchstaben der quer parkenden Autos befüllt an den Indexen an denen sie die
normalen Parkplätze blockieren.<br>
mit den Buchstaben der quer parkenden Autos befüllt an den Indexen, an denen sie die
normalen Parkplätze blockieren.
In einer for-Schleife wird die "move"-Funktion je Index der Parkplätze doppelt
für beide Verschiebungsrichtungen aufgerufen.
In der "move"-Funktion wird ein Auto verschoben, wenn nicht das Ende des
Parkplatzes erreicht ist. Die Funktion ruft sich recursive auf um weitere Autos zu
verschieben. Je nachdem in welche Richtung weniger Autos verschoben werden müssen
oder, wenn es gleich viele sind, wo die Anzahl der verschobenen Plätze aller Autos
geringer ist, wird sich für das Verschieben in diese Richtung entschieden.
Parkplatzes erreicht ist. Die Funktion ruft sich rekursiv auf, um weitere Autos zu
verschieben. Je nachdem, in welche Richtung weniger Autos verschoben werden müssen,
wird sich für das Verschieben in diese Richtung entschieden.
Wenn es allerdings gleich viele sind, ist die geringere Anzahl der verschobenen
Plätze aller Autos ausschlaggebend für das Verschieben in diese Richtung.
## Beispiele
@ -129,7 +133,7 @@ Außerdem habe ich noch weitere Testfälle erstellt, die sich im Ordner "testdat
befinden. Als Erstes habe ich getestet, ob das Programm auch mit dem Verschieben
sehr vieler Autos klarkommt. Es gibt 26 Parkplätze, wovon alle außer die ersten
beiden mit quer parkenden Autos blockiert sind. Für die quer parkenden Autos
wurde Kleinbuchstaben verwendet, da alle Großbuchstaben schon belegt sind.
wurden Kleinbuchstaben verwendet, da alle Großbuchstaben schon belegt sind.
```
test0.txt:
@ -149,22 +153,33 @@ M: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links
N: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links
O: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links
P: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links
Q: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links
R: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links
S: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links
T: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links
U: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links, j 2 links
V: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links, j 1 links
W: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links, j 2 links, k 2 links
X: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links, j 1 links, k 1 links
Y: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links, j 2 links, k 2 links, l 2 links
Z: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links, j 1 links, k 1 links, l 1 links
Q: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links
R: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links
S: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links
T: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links
U: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links, j 2 links
V: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links, j 1 links
W: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links, j 2 links, k 2 links
X: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links, j 1 links, k 1 links
Y: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links, j 2 links, k 2 links, l 2 links
Z: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links, j 1 links, k 1 links, l 1 links
```
Die Autos wurden abwechselend jeweils ein oder zwei Parkplätze verschoben,
je nachdem ob das ausfahrende Auto hinter der linke oder rechten Hälfe des quer
stehenden Autos steht.<br>
Die Bezeichner der Autos müssen auch nicht bei A beginnen; der Beginn bei
Die Autos wurden abwechselend jeweils um ein oder zwei Parkplätze verschoben,
je nachdem ob das ausfahrende Auto hinter der linken oder rechten Hälfe des quer
stehenden Autos steht.
Die Bezeichner der Autos müssen auch nicht bei A beginnen. Der Beginn mit
anderen Buchstaben ist möglich. Dies zeigt das folgende Beispiel an der
Eingabedatei "parkplatz3.txt" mit veränderten Bezeichnern.
@ -185,72 +200,3 @@ N: Q 1 links, R 1 links
O: Q 2 links, R 2 links, S 2 links
P: Q 1 links, R 1 links, S 1 links
```
## Quelltext
```
func main() {
for i := range querAutos {
var currentMoves []movedCar // enthält die Verschiebungen der Autos in die Richtung in der weniger Autos verschoben werden müssen
var carLeastSteps uint32
for _, direction := range []int{-1, 1} { // -1 steht für links und 1 für rechts
movedCars, steps, success := move(i, direction, []movedCar{}, 0, 0)
/* Wenn das Verschieben der Autos in der jeweiligen Richtung erfolgreich ist und noch keine
Verschiebungen abgespeichert wurden, d. h. gerade die Verschiebungen für links berechnet
wurden oder das Verschieben nach links nicht erfolgreich war, da das Ende das Parkplatzes
erreicht wurde, dann werden die Verschiebungen abgespeichert.
Sollten allerdings bereits Verschiebungen für links vorhanden sein, wird das Verschieben nach
rechts bevorzugt, wenn weniger Autos verschoben werden mussten oder die Autos weniger Plätze
verschoben werden mussten. */
if success && (currentMoves == nil || len(movedCars) < len(currentMoves) || len(movedCars) == len(currentMoves) && steps < carLeastSteps) {
currentMoves = movedCars
carLeastSteps = steps
}
}
}
}
// Funktion zur Berechung der Autos, die für einen Parkplatz verschoben werden müssen.
func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uint32) ([]movedCar, uint32, bool) {
querAuto := querAutos[i]
/* Wenn querAuto gleich 0 ist, ist kein Auto vor dem Parkplatz.
Wenn es das gleiche Auto ist wie das zuletzt verschobene, ist auch das Verschieben beendet,
da dieses Auto bereits ausreichend verschoben wurde. */
if querAuto == 0 || querAuto == lastMoved {
return movedCars, totalSteps, true
}
/* Wenn neben unserem Auto in der jeweiligen Richtung kein Parkplatz mehr ist,
dann können auch keine Autos in diese Richtung verschoben werden. */
if outOfBounds(querAutos, i + direction) {
return movedCars, totalSteps, false
}
var steps int
/* Wenn sich eins nach der Verschiebungsrichtung auch unserer quer parkendes Auto befindet,
muss es nur um einen Platz verschoben werden, ansonsten um zwei. */
if querAutos[i + direction] == querAuto {
steps = 1
} else {
steps = 2
}
endCar := i + direction * 2 // ist das Ende des verschobenen Autos, das realtiv zur verschobenen Richtung, vorne ist.
/* müsste das Auto ausserhalb des Parkplatzes geschoben werden,
damit unser normale Parkplatz frei wird, ist das Verschieben in diese Richtung nicht möglich. */
if outOfBounds(querAutos, endCar) {
return movedCars, totalSteps, false
}
// fügt das gerade verschobene Auto der Slice mit den verschobenen Autos hinzu.
movedCars = append(movedCars, movedCar{querAuto, steps, direction})
/* ruft die Funktion recursive auf, mit dem Index des Parkplatzes an dem
noch ein quer stehendes Auto stehen könnte, das verschoben werden müsste. */
return move(endCar, direction, movedCars, querAuto, totalSteps + uint32(steps))
}
// Funktion um zu überprüfen, ob ein Index innerhalb einer Slice liegt.
func outOfBounds(slice []byte, i int) bool {
return i < 0 || i >= len(slice)
}
```

View File

@ -17,7 +17,7 @@ type movedCar struct {
var querAutos []byte
func main() {
// Dem Programm können beliebig viele Eingabedatein übergeben werden.
// Dem Programm können beliebig viele Eingabedateien übergeben werden.
for _, filepath := range os.Args[1:] {
// ausgeben des Dateipfades, um Zuordnung der Lösung zu der entsprechenden Eingabedatei zu ermöglichen
fmt.Printf("%s:\n", filepath)
@ -39,7 +39,7 @@ func main() {
if len(line) == 0 {
continue
}
// Die Position des des quer stehenden Autos beginnt ab dem 3. Zeichen (Index 2) bis zum Ende der Zeile.
// Die Position des quer stehenden Autos beginnt ab dem 3. Zeichen (Index 2) bis zum Ende der Zeile.
i, err := strconv.Atoi(line[2:])
throw(err)
// Jedes quer stehende Auto blockiert zwei Parkplätze. Deshalb belegt es auch zwei Plätze in unserer Slice.
@ -52,12 +52,14 @@ func main() {
movedCars, steps, success := move(i, direction, []movedCar{}, 0, 0)
/* Wenn das Verschieben der Autos in der jeweiligen Richtung erfolgreich ist und noch keine
Verschiebungen abgespeichert wurden, d. h. gerade die Verschiebungen für links berechnet
wurden oder das Verschieben nach links nicht erfolgreich war, da das Ende das Parkplatzes
erreicht wurde, dann werden die Verschiebungen abgespeichert.
Verschiebungen abgespeichert wurden, werden die Verschiebungen abgespeichert.
Es wurden vorher noch keine Verschiebungen gespeichert, wenn gerade die Verschiebungen
für links berechnet wurden oder das Verschieben nach links nicht erfolgreich war,
da das Ende das Parkplatzes erreicht wurde.
Sollten allerdings bereits Verschiebungen für links vorhanden sein, wird das Verschieben nach
rechts bevorzugt, wenn weniger Autos verschoben werden mussten oder die Autos weniger Plätze
verschoben werden mussten. */
rechts bevorzugt, wenn weniger Autos verschoben werden mussten.
Wenn es allerdings gleich viele sind, ist die geringere Anzahl der verschobenen
Plätze aller Autos ausschlaggebend für das Verschieben in diese Richtung. */
if success && (currentMoves == nil || len(movedCars) < len(currentMoves) || len(movedCars) == len(currentMoves) && steps < carLeastSteps) {
currentMoves = movedCars
carLeastSteps = steps
@ -109,7 +111,7 @@ func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uin
return movedCars, totalSteps, false
}
var steps int
/* Wenn sich eins nach der Verschiebungsrichtung auch unserer quer parkendes Auto befindet,
/* Wenn sich in der Verschiebungsrichtung direkt daneben auch unserer quer parkendes Auto befindet,
muss es nur um einen Platz verschoben werden, ansonsten um zwei. */
if querAutos[i + direction] == querAuto {
steps = 1
@ -118,14 +120,14 @@ func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uin
}
endCar := i + direction * 2 // ist das Ende des verschobenen Autos, das realtiv zur verschobenen Richtung, vorne ist.
/* müsste das Auto ausserhalb des Parkplatzes geschoben werden,
damit unser normale Parkplatz frei wird, ist das Verschieben in diese Richtung nicht möglich. */
/* müsste das Auto außerhalb des Parkplatzes geschoben werden,
damit unser normaler Parkplatz frei wird, ist das Verschieben in diese Richtung nicht möglich. */
if outOfBounds(querAutos, endCar) {
return movedCars, totalSteps, false
}
// fügt das gerade verschobene Auto der Slice mit den verschobenen Autos hinzu.
movedCars = append(movedCars, movedCar{querAuto, steps, direction})
/* ruft die Funktion recursive auf, mit dem Index des Parkplatzes an dem
/* ruft die Funktion rekursiv auf, mit dem Index des Parkplatzes an dem
noch ein quer stehendes Auto stehen könnte, das verschoben werden müsste. */
return move(endCar, direction, movedCars, querAuto, totalSteps + uint32(steps))
}