92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
package day22
|
|
|
|
import (
|
|
"adventofcode2024/utils"
|
|
rb "adventofcode2024/utils/ringbuffer"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func Part1(input string) int {
|
|
var secret uint
|
|
total := 0
|
|
secrets := strings.Split(input, "\n")
|
|
for _, secret_str := range secrets {
|
|
secret = uint(utils.MustAtoi(secret_str))
|
|
for i := 0; i < 2000; i++ {
|
|
secret ^= secret * 64
|
|
secret %= 16777216
|
|
secret ^= secret / 32
|
|
secret %= 16777216
|
|
secret ^= secret * 2048
|
|
secret %= 16777216
|
|
}
|
|
total += int(secret)
|
|
}
|
|
return total
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
var secret uint
|
|
var banannas0, banannas1, banannas2, banannas3, banannas4 int
|
|
seq_map := make(map[string]int)
|
|
total := 0
|
|
ringBuffer := rb.NewRingBuffer[uint](5)
|
|
|
|
secrets := strings.Split(input, "\n")
|
|
for _, secret_str := range secrets {
|
|
found_map := make(map[string]bool)
|
|
secret = uint(utils.MustAtoi(secret_str))
|
|
for i := 0; i < 2000; i++ {
|
|
secret = get_next_secret(secret)
|
|
ringBuffer.Add(secret)
|
|
if ringBuffer.Len() < 5 { continue }
|
|
ring := ringBuffer.Get()
|
|
banannas0 = get_bannnas(ring[0])
|
|
banannas1 = get_bannnas(ring[1])
|
|
banannas2 = get_bannnas(ring[2])
|
|
banannas3 = get_bannnas(ring[3])
|
|
banannas4 = get_bannnas(ring[4])
|
|
map_str := diff_bannanas(banannas1, banannas0) +
|
|
diff_bannanas(banannas2, banannas1) +
|
|
diff_bannanas(banannas3, banannas2) +
|
|
diff_bannanas(banannas4, banannas3)
|
|
if _, ok := found_map[map_str]; !ok {
|
|
seq_map[map_str] += banannas4
|
|
found_map[map_str] = true
|
|
}
|
|
}
|
|
}
|
|
for _, v := range seq_map {
|
|
if v > total {
|
|
total = v
|
|
}
|
|
}
|
|
return total
|
|
}
|
|
|
|
func get_next_secret(in uint) uint {
|
|
in ^= in * 64
|
|
in %= 16777216
|
|
in ^= in / 32
|
|
in %= 16777216
|
|
in ^= in * 2048
|
|
in %= 16777216
|
|
return in
|
|
}
|
|
|
|
func get_bannnas(secret uint) int {
|
|
return int(secret) % 10
|
|
}
|
|
|
|
func diff_bannanas(a, b int) string {
|
|
ret := ""
|
|
diff := a - b
|
|
if diff >= 0 {
|
|
ret = "+" + strconv.Itoa(diff)
|
|
} else {
|
|
ret = strconv.Itoa(diff)
|
|
}
|
|
return ret
|
|
}
|