145 lines
2.9 KiB
Go
145 lines
2.9 KiB
Go
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)
|
|
}
|