package day21 import ( "bytes" "fmt" "strconv" "strings" "tools" ) var revIndex = map[int]int{ 0: 1, 1: 1, 2: 6, 3: 2, 4: 7, 5: 3, 6: 8, 7: 4, } func scramble(s string, instr []string, reverse bool) string { sb := []byte(s) for _, inst := range instr { parts := strings.Split(inst, " ") if parts[0] == "swap" && parts[1] == "position" { x, _ := strconv.Atoi(parts[2]) y, _ := strconv.Atoi(parts[5]) sb[x], sb[y] = sb[y], sb[x] } else if parts[0] == "swap" && parts[1] == "letter" { x := bytes.Index(sb, []byte(parts[2])) y := bytes.Index(sb, []byte(parts[5])) sb[x], sb[y] = sb[y], sb[x] } else if parts[0] == "rotate" && parts[1] == "left" { x, _ := strconv.Atoi(parts[2]) if reverse { sb = append(sb[len(sb)-(x%len(sb)):], sb[:len(sb)-(x%len(sb))]...) } else { sb = append(sb[x%len(sb):], sb[:x%len(sb)]...) } } else if parts[0] == "rotate" && parts[1] == "right" { x, _ := strconv.Atoi(parts[2]) if reverse { sb = append(sb[x%len(sb):], sb[:x%len(sb)]...) } else { sb = append(sb[len(sb)-(x%len(sb)):], sb[:len(sb)-(x%len(sb))]...) } } else if parts[0] == "rotate" && parts[1] == "based" { var x int if reverse { x = bytes.Index(sb, []byte(parts[6])) x = revIndex[x] sb = append(sb[x%len(sb):], sb[:x%len(sb)]...) } else { x = bytes.Index(sb, []byte(parts[6])) if x >= 4 { x++ } x++ sb = append(sb[len(sb)-(x%len(sb)):], sb[:len(sb)-(x%len(sb))]...) } } else if parts[0] == "reverse" && parts[1] == "positions" { x, _ := strconv.Atoi(parts[2]) y, _ := strconv.Atoi(parts[4]) var ns []byte for i := 0; i < x; i++ { ns = append(ns, sb[i]) } for i := y; i >= x; i-- { ns = append(ns, sb[i]) } sb = append(ns, sb[y+1:]...) } else if parts[0] == "move" && parts[1] == "position" { x, _ := strconv.Atoi(parts[2]) y, _ := strconv.Atoi(parts[5]) if reverse { c := sb[y] sb = append(sb[:y], sb[y+1:]...) sb = append(sb[:x+1], sb[x:]...) sb[x] = c } else { c := sb[x] sb = append(sb[:x], sb[x+1:]...) sb = append(sb[:y+1], sb[y:]...) sb[y] = c } } else { fmt.Println("ERROR: unknown instruction:", inst) } } return string(sb) } func Part1(puzzle tools.AoCPuzzle) interface{} { inp := puzzle.GetInputArray() startString := inp[0] password := scramble(startString, inp[1:], false) return password } func Part2(puzzle tools.AoCPuzzle) interface{} { inp := puzzle.GetInputArray() var rinp []string for x := len(inp) - 1; x > 0; x-- { rinp = append(rinp, inp[x]) } startString := "fbgdceah" //startString := "gfdhebac" password := scramble(startString, rinp, true) return password }