2016-day21: gross scrambling and then checking permutations

This commit is contained in:
alexchao26
2020-12-24 21:39:50 -05:00
parent d1a81dcfcb
commit 207d088a09
3 changed files with 176 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
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.MakeStringPermutations(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
}
+38
View File
@@ -0,0 +1,38 @@
package main
import (
"testing"
"github.com/alexchao26/advent-of-code-go/util"
)
var example = `swap position 4 with position 0
swap letter d with letter b
reverse positions 0 through 4
rotate left 1 step
move position 1 to position 4
move position 3 to position 0
rotate based on position of letter b
rotate based on position of letter d`
func Test_part1(t *testing.T) {
type args struct {
input, starting, target string
}
tests := []struct {
name string
args args
want string
}{
{"part1 example", args{example, "abcde", ""}, "decab"},
{"part1 actual", args{util.ReadFile("input.txt"), "abcdefgh", ""}, "bfheacgd"},
{"part2 actual", args{util.ReadFile("input.txt"), "abcdefgh", "fbgdceah"}, "gcehdbfa"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := part1(tt.args.input, tt.args.starting, tt.args.target); got != tt.want {
t.Errorf("part1() = %v, want %v", got, tt.want)
}
})
}
}