115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
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
|
|
}
|