basic a2
This commit is contained in:
@ -5,7 +5,6 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"strconv"
|
||||
"math"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
@ -18,39 +17,62 @@ type movedCar struct {
|
||||
var querAutos []byte
|
||||
|
||||
func main() {
|
||||
// Dem Programm können beliebig viele Eingabedatein übergeben werden.
|
||||
for _, filepath := range os.Args[1:] {
|
||||
fmt.Printf("%s: \n", filepath)
|
||||
rawFile, err := ioutil.ReadFile(filepath)
|
||||
// ausgeben des Dateipfades, um Zuordnung der Lösung zu der entsprechenden Eingabedatei zu ermöglichen
|
||||
fmt.Printf("%s:\n", filepath)
|
||||
|
||||
rawFile, err := ioutil.ReadFile(filepath) // lesen der Eingabedatei
|
||||
throw(err)
|
||||
input := string(rawFile)
|
||||
firstChar := input[0]
|
||||
|
||||
firstChar := input[0] // firstChar ist der Buchstabe mit dem das erste Auto gekennzeichnet wird.
|
||||
|
||||
/* querAutos ist ein Array bzw. slice, wie dynamisch vergrößerbare Arrays in Go benannt werden,
|
||||
welches die Autos, die quer auf dem Parkplatz parken, enthält. input[2] ist der Buchstabe vom letztem Auto.
|
||||
Die Größe der slice bzw. die Anzahl der senkrecht parkenden Autos wird durch die Differenz der ASCII Codes
|
||||
berechnet. */
|
||||
querAutos = make([]byte, input[2] - firstChar + 1)
|
||||
// teilt den Text in Zeilen auf und iteriert über die Zeilen ab Zeile 3
|
||||
for _, line := range strings.Split(input, "\n")[2:] {
|
||||
// auf Unix Systemen enden die Textdatei auf einem newline Zeichen. Deshalb hat unsere letzte "Zeile" die Länge 0 und wird übersprungen.
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
// Die Position des 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.
|
||||
querAutos[i], querAutos[i + 1] = line[0], line[0]
|
||||
}
|
||||
for i := range querAutos {
|
||||
var currentMoves []movedCar
|
||||
var carLeastSteps uint32 = math.MaxUint32
|
||||
for _, direction := range []int{-1, 1} {
|
||||
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
|
||||
}
|
||||
}
|
||||
// sortiert die verschoben Autos alphabetisch
|
||||
sort.Slice(currentMoves, func(i, j int) bool {
|
||||
return currentMoves[i].id < currentMoves[j].id
|
||||
})
|
||||
fmt.Printf("%s: ", string(firstChar + byte(i)))
|
||||
fmt.Printf("%s: ", string(firstChar + byte(i))) // gibt den Buchstaben für das jeweilige Auto auf den normalen Parkplatz aus.
|
||||
for j, car := range currentMoves {
|
||||
if(j != 0) {
|
||||
fmt.Print(", ")
|
||||
}
|
||||
// gibt aus welches Auto wie viele Plätze in welche Richtung verschoben wurde.
|
||||
fmt.Printf("%s %d ", string(car.id), car.steps)
|
||||
if car.direction == 1 {
|
||||
fmt.Print("rechts")
|
||||
@ -63,34 +85,52 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion um im Falle eines Fehlers, den Fehler auszugeben und das Programm zu beenden.
|
||||
func throw(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user