package main import ( "bufio" "fmt" "os" "slices" "strconv" ) func main() { fmt.Println(part1([]int64{1, 10, 100, 2024}), 37327623) fmt.Println(part1(readData("data.txt")), 13004408787) fmt.Println(part2([]int64{1, 2, 3, 2024}), 23) fmt.Println(part2(readData("data.txt"))) } func part1(init []int64) (result int64) { for _, n := range init { for range 2000 { n = next(n) } result += n } return } func makeChangeId(memory [4]int, i int) (result int) { for j := range 4 { result = result*19 + memory[(i+j)%4] + 9 } return } func part2(init []int64) int { priceForChangeId := make([]int, 19*19*19*19) for _, n := range init { seenChange := make([]bool, 19*19*19*19) prevPrice := n % 10 memory := [4]int{0, 0, 0, 0} for i := range 2000 { n2 := next(n) price := n2 % 10 change := price - prevPrice memory[i%4] = int(change) if i >= 3 { changeId := makeChangeId(memory, i) if !seenChange[changeId] { seenChange[changeId] = true priceForChangeId[changeId] += int(price) } } n, prevPrice = n2, price } } return slices.Max(priceForChangeId) } func prune(a int64) int64 { return a % 16777216 } func next(a int64) int64 { a = prune((a << 6) ^ a) a = prune((a >> 5) ^ a) a = prune((a << 11) ^ a) return a } func readData(fileName string) (numbers []int64) { fp, _ := os.Open(fileName) scanner := bufio.NewScanner(fp) for scanner.Scan() { n, _ := strconv.ParseInt(scanner.Text(), 10, 64) numbers = append(numbers, n) } return }