package main import ( "bufio" "fmt" "os" "strconv" "strings" "time" ) func main() { start := time.Now() partOne() duration := time.Since(start) partTwo() duration2 := time.Since(start) fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) } func cupInList(cup int, cups []int) bool { for _, c := range cups { if c == cup { return true } } return false } func generateFullCupset(cups []int, totalCups int) []int { for i := len(cups); i < totalCups; i = i + 1 { cups = append(cups, i) } return cups } func findTargetCupIndex(cup int, cups []int) int { for i, c := range cups { if c == cup { return i } } return 0 // uh-oh } func step(cups []int) []int { cupCount := len(cups) currentCup := cups[0] removedCups := cups[1:4] newList := make([]int, 0, cupCount) newList = append([]int{cups[0]}, cups[4:]...) var targetCup int if currentCup == 1 { targetCup = cupCount } else { targetCup = currentCup - 1 } for cupInList(targetCup, removedCups) { targetCup = targetCup - 1 if targetCup == 0 { targetCup = cupCount } } tc := findTargetCupIndex(targetCup, newList) result := make([]int, 0, cupCount) result = append(result, newList[1:tc+1]...) result = append(result, removedCups...) result = append(result, newList[tc+1:]...) result = append(result, newList[0]) return result } func runabout(cups []int) string { oneIndex := findTargetCupIndex(1, cups) result := "" for i := oneIndex + 1; i < len(cups); i = i + 1 { result = result + strconv.Itoa(cups[i]) } for i := 0; i < len(cups[:oneIndex]); i = i + 1 { result = result + strconv.Itoa(cups[i]) } return result } func nextTwo(cups []int) (int, int) { oneIndex := findTargetCupIndex(1, cups) if oneIndex+1 > len(cups) { return cups[0], cups[1] } if oneIndex+2 > len(cups) { return cups[len(cups)], cups[0] } return cups[oneIndex+1], cups[oneIndex+2] } func partOne() { f, _ := os.Open("testinput") reader := bufio.NewReader(f) scanner := bufio.NewScanner(reader) cups := []int{} scanner.Scan() for _, s := range strings.Split(scanner.Text(), "") { i, _ := strconv.Atoi(s) cups = append(cups, i) } for i := 0; i < 100; i = i + 1 { cups = step(cups) } fmt.Println(runabout(cups)) } func partTwo() { f, _ := os.Open("testinput") reader := bufio.NewReader(f) scanner := bufio.NewScanner(reader) cups := []int{} scanner.Scan() for _, s := range strings.Split(scanner.Text(), "") { i, _ := strconv.Atoi(s) cups = append(cups, i) } allCups := generateFullCupset(cups, 10000000) for i := 0; i < 10000000; i = i + 1 { allCups = step(allCups) fmt.Println(i) } fmt.Println(nextTwo(allCups)) }