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 }