package main import ( "flag" "fmt" "strings" "github.com/alexchao26/advent-of-code-go/algos" "github.com/alexchao26/advent-of-code-go/cast" "github.com/alexchao26/advent-of-code-go/util" ) func main() { var part int flag.IntVar(&part, "part", 1, "part 1 or 2") flag.Parse() fmt.Println("Running part", part) var ans string if part == 1 { ans = part1(util.ReadFile("./input.txt"), "abcdefgh", "") } else { ans = part1(util.ReadFile("./input.txt"), "abcdefgh", "fbgdceah") } fmt.Println("Output:", ans) } func part1(input string, starting string, target string) string { runSteps := func(starting string) string { registers := strings.Split(starting, "") for _, inst := range strings.Split(input, "\n") { registers = modifySlice(inst, registers) } return strings.Join(registers, "") } // part 1 if target == "" { return runSteps(starting) } for _, p := range algos.PermuteString(starting) { if runSteps(p) == target { return p } } panic("no perms matched") } func modifySlice(line string, sli []string) []string { switch { case strings.HasPrefix(line, "swap"): var i1, i2 int if strings.Contains(line, "position") { fmt.Sscanf(line, "swap position %d with position %d", &i1, &i2) } else { var c1, c2 string fmt.Sscanf(line, "swap letter %1s with letter %1s", &c1, &c2) i1, i2 = getIndex(sli, c1), getIndex(sli, c2) } sli[i1], sli[i2] = sli[i2], sli[i1] case strings.HasPrefix(line, "rotate"): var rightShift int parts := strings.Split(line, " ") if strings.Contains(line, "letter") { index := getIndex(sli, parts[6]) if index >= 4 { index++ } index++ rightShift = index % len(sli) } else { // left or right rightShift = cast.ToInt(parts[2]) if parts[1] == "left" { rightShift = len(sli) - rightShift } } // perform shift sli = append(sli[len(sli)-rightShift:], sli[:len(sli)-rightShift]...) case strings.HasPrefix(line, "reverse"): var i1, i2 int fmt.Sscanf(line, "reverse positions %d through %d", &i1, &i2) for i1 < i2 { sli[i1], sli[i2] = sli[i2], sli[i1] i1++ i2-- } case strings.HasPrefix(line, "move"): var i1, i2 int fmt.Sscanf(line, "move position %d to position %d", &i1, &i2) store := sli[i1] // remove char at i1 copy(sli[i1:], sli[i1+1:]) for i := len(sli) - 1; i >= i2+1; i-- { sli[i] = sli[i-1] } sli[i2] = store default: panic("unhandled instruction type: " + line) } // return modified slice return sli } func getIndex(letters []string, toFind string) int { for i, v := range letters { if v == toFind { return i } } return -1 }