final commit
This commit is contained in:
@ -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)
|
||||
}
|
||||
```
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user