mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-19 03:23:27 +02:00
2016-day21: gross scrambling and then checking permutations
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package algos
|
package algos
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
// MakePermutations will make all permutations of the numbers input
|
// MakePermutations will make all permutations of the numbers input
|
||||||
// returns a pointer to avoid copying a large number of permutations
|
// returns a pointer to avoid copying a large number of permutations
|
||||||
func MakePermutations(numbers []int) *[][]int {
|
func MakePermutations(numbers []int) *[][]int {
|
||||||
@@ -32,3 +34,22 @@ func swapRecurseBacktrack(numbers []int, startIndex int, results *[][]int) {
|
|||||||
numbers[startIndex], numbers[i] = numbers[i], numbers[startIndex]
|
numbers[startIndex], numbers[i] = numbers[i], numbers[startIndex]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeStringPermutations generates all permutations for a given string
|
||||||
|
func MakeStringPermutations(str string) []string {
|
||||||
|
return recurse(strings.Split(str, ""), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func recurse(sli []string, index int) []string {
|
||||||
|
if index == len(sli) {
|
||||||
|
return []string{strings.Join(sli, "")}
|
||||||
|
}
|
||||||
|
|
||||||
|
var perms []string
|
||||||
|
for i := index; i < len(sli); i++ {
|
||||||
|
sli[i], sli[index] = sli[index], sli[i]
|
||||||
|
perms = append(perms, recurse(sli, index+1)...)
|
||||||
|
sli[i], sli[index] = sli[index], sli[i]
|
||||||
|
}
|
||||||
|
return perms
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user