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 }