aoc2016/archive/day21/day.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
}