summaryrefslogtreecommitdiff
path: root/day22/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'day22/main.go')
-rw-r--r--day22/main.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/day22/main.go b/day22/main.go
new file mode 100644
index 0000000..992afd1
--- /dev/null
+++ b/day22/main.go
@@ -0,0 +1,80 @@
+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
+}