96 lines
1.8 KiB
Go
96 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
var progs string
|
|
length := 16
|
|
iters := 1000000000
|
|
if len(os.Args) > 1 {
|
|
length = Atoi(os.Args[1])
|
|
if len(os.Args) > 2 {
|
|
iters = Atoi(os.Args[2])
|
|
}
|
|
}
|
|
|
|
// Create a starting string
|
|
for i := 0; i < length; i++ {
|
|
progs += string('a' + i)
|
|
}
|
|
|
|
inp := StdinToString()
|
|
moves := strings.Split(inp, ",")
|
|
|
|
var loopEnd int
|
|
var state []string
|
|
doneProgs := progs
|
|
state = append(state, progs)
|
|
for loopEnd = 1; loopEnd < (iters / 2); loopEnd++ {
|
|
doneProgs = doDance(doneProgs, moves)
|
|
state = append(state, doneProgs)
|
|
if doneProgs == progs {
|
|
fmt.Println("Loops at", loopEnd)
|
|
pos := (iters / loopEnd) * loopEnd
|
|
fmt.Println("Final State", state[iters-pos])
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func doDance(progs string, moves []string) string {
|
|
for _, v := range moves {
|
|
switch v[0] {
|
|
case 's':
|
|
progs = Spin(progs, Atoi(v[1:]))
|
|
case 'p':
|
|
pts := strings.Split(v[1:], "/")
|
|
progs = Partner(progs, pts[0], pts[1])
|
|
case 'x':
|
|
pts := strings.Split(v[1:], "/")
|
|
progs = Exchange(progs, Atoi(pts[0]), Atoi(pts[1]))
|
|
}
|
|
}
|
|
return progs
|
|
}
|
|
|
|
func Spin(progs string, cnt int) string {
|
|
stSpin := len(progs) - cnt
|
|
return progs[stSpin:] + progs[:stSpin]
|
|
}
|
|
|
|
func Exchange(progs string, i1, i2 int) string {
|
|
if i1 > i2 {
|
|
i1, i2 = i2, i1
|
|
}
|
|
return progs[:i1] + string(progs[i2]) + progs[i1+1:i2] + string(progs[i1]) + progs[i2+1:]
|
|
}
|
|
|
|
func Partner(progs string, p1, p2 string) string {
|
|
return Exchange(progs, strings.Index(progs, p1), strings.Index(progs, p2))
|
|
}
|
|
|
|
func StdinToString() string {
|
|
var input string
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
for scanner.Scan() {
|
|
input = scanner.Text()
|
|
}
|
|
return input
|
|
}
|
|
|
|
func Atoi(i string) int {
|
|
var ret int
|
|
var err error
|
|
if ret, err = strconv.Atoi(i); err != nil {
|
|
log.Fatal("Invalid Atoi")
|
|
}
|
|
return ret
|
|
}
|