package day20 import ( "bufio" "fmt" "os" "strconv" ) func printNumbers(numbers []int, nexts []int) { current := 0 for nexts[current] == -1 { current += 1 } first := numbers[current] fmt.Printf("%d", first) current = nexts[current] for numbers[current] != first { fmt.Printf(" %d", numbers[current]) current = nexts[current] } fmt.Println() } func removeIndex(idx int, prevs []int, nexts []int) (before int, after int) { before = prevs[idx] after = nexts[idx] nexts[before] = after prevs[after] = before prevs[idx] = -1 nexts[idx] = -1 return } func insertAfter(idx int, after int, prevs []int, nexts []int) { afterNext := nexts[after] prevs[idx] = after nexts[idx] = afterNext prevs[afterNext] = idx nexts[after] = idx } func insertBefore(idx int, before int, prevs []int, nexts []int) { beforePrev := prevs[before] prevs[idx] = beforePrev nexts[idx] = before prevs[before] = idx nexts[beforePrev] = idx } func shift(count int, idx int, prevs []int, nexts []int) { count %= len(prevs) - 1 for count != 0 { before, after := removeIndex(idx, prevs, nexts) if count > 0 { insertAfter(idx, after, prevs, nexts) count -= 1 } else { insertBefore(idx, before, prevs, nexts) count += 1 } } } func indexPast(count int, current int, nexts []int) int { for count > 0 { current = nexts[current] count -= 1 } return current } func Run(filename string, keyString string, countString string) { file, err := os.Open(filename) if err != nil { fmt.Println("Error opening file:", err) return } key, err := strconv.Atoi(keyString) if err != nil { fmt.Println("Invalid key value", err) return } roundCount, err := strconv.Atoi(countString) if err != nil { fmt.Println("Invalid round count", err) return } scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) numbers := []int{} nexts := []int{} prevs := []int{} zeroIndex := -1 for scanner.Scan() { line := scanner.Text() x, err := strconv.Atoi(line) if err != nil { fmt.Println("Couldn't parse number", line) return } numbers = append(numbers, x*key) nexts = append(nexts, 0) prevs = append(prevs, 0) if x == 0 { zeroIndex = len(numbers) - 1 } } for idx := range nexts { nexts[idx] = (idx + 1) % len(nexts) if idx == 0 { prevs[idx] = len(prevs) - 1 } else { prevs[idx] = idx - 1 } } file.Close() for round := 0; round < roundCount; round++ { for idx := range numbers { fmt.Println("Working round", round+1, "index", idx, "with value/count", numbers[idx]) shift(numbers[idx], idx, prevs, nexts) //printNumbers(numbers, nexts) } } idx1k := indexPast(1000, zeroIndex, nexts) idx2k := indexPast(1000, idx1k, nexts) idx3k := indexPast(1000, idx2k, nexts) val1k := numbers[idx1k] val2k := numbers[idx2k] val3k := numbers[idx3k] fmt.Println("Value 1k after 0", val1k, "2k", val2k, "3k", val3k, "sum", val1k+val2k+val3k) }