mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
118 lines
2.6 KiB
Go
118 lines
2.6 KiB
Go
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
|
|
}
|