package main import ( "os" "io/ioutil" "strings" "strconv" "math" "fmt" "sort" ) type movedCar struct { id byte steps int direction int } var querAutos []byte func main() { for _, filepath := range os.Args[1:] { fmt.Printf("%s: \n", filepath) rawFile, err := ioutil.ReadFile(filepath) throw(err) input := string(rawFile) firstChar := input[0] querAutos = make([]byte, input[2] - firstChar + 1) for _, line := range strings.Split(input, "\n")[2:] { if len(line) == 0 { continue } i, err := strconv.Atoi(line[2:]) throw(err) 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} { movedCars, steps, success := move(i, direction, []movedCar{}, 0, 0) if success && (currentMoves == nil || len(movedCars) < len(currentMoves) || len(movedCars) == len(currentMoves) && steps < carLeastSteps) { currentMoves = movedCars carLeastSteps = steps } } sort.Slice(currentMoves, func(i, j int) bool { return currentMoves[i].id < currentMoves[j].id }) fmt.Printf("%s: ", string(firstChar + byte(i))) for j, car := range currentMoves { if(j != 0) { fmt.Print(", ") } fmt.Printf("%s %d ", string(car.id), car.steps) if car.direction == 1 { fmt.Print("rechts") } else { fmt.Print("links") } } fmt.Println() } } } func throw(err error) { if err != nil { panic(err) } } func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uint32) ([]movedCar, uint32, bool) { querAuto := querAutos[i] if querAuto == 0 || querAuto == lastMoved { return movedCars, totalSteps, true } if outOfBounds(querAutos, i + direction) { return movedCars, totalSteps, false } var steps int if querAutos[i + direction] == querAuto { steps = 1 } else { steps = 2 } endCar := i + direction * 2 if outOfBounds(querAutos, endCar) { return movedCars, totalSteps, false } movedCars = append(movedCars, movedCar{querAuto, steps, direction}) return move(endCar, direction, movedCars, querAuto, totalSteps + uint32(steps)) } func outOfBounds(slice []byte, i int) bool { return i < 0 || i >= len(slice) }