Added all code for day 22

This commit is contained in:
Ceferino Patino 2024-12-21 23:59:25 -06:00
commit f4e07115c7
Signed by: c4patino
SSH key fingerprint: SHA256:9fQ9TsujGrdNNi76mnsu63v7dS5JOmHRZEqBOl49OR8
5 changed files with 2430 additions and 0 deletions

View file

@ -30,6 +30,7 @@ import (
"cpatino.com/advent-of-code/2024/day19"
"cpatino.com/advent-of-code/2024/day20"
"cpatino.com/advent-of-code/2024/day21"
"cpatino.com/advent-of-code/2024/day22"
)
var days = map[int]func(string) (interface{}, interface{}){
@ -54,6 +55,7 @@ var days = map[int]func(string) (interface{}, interface{}){
19: day19.Run,
20: day20.Run,
21: day21.Run,
22: day22.Run,
}
var rootCmd = &cobra.Command{

134
2024/day22/day22.go Executable file
View file

@ -0,0 +1,134 @@
package day22
import (
"bufio"
"os"
"strconv"
"sync"
)
type SharedStore struct {
Store map[string]int
Lock sync.Mutex
}
func secretIterator(initial int, limit int) func() (int, bool) {
current := initial
count := 0
return func() (int, bool) {
if count >= limit {
return -1, false
}
current = (current ^ (current * 64)) % 16777216
current = (current ^ (current / 32)) % 16777216
current = (current ^ (current * 2048)) % 16777216
count += 1
return current, true
}
}
func Part1(secrets []int) int {
sum := 0
for _, secret := range secrets {
iter := secretIterator(secret, 2000)
last := -1
for secret, ok := iter(); ok; secret, ok = iter() {
last = secret
}
sum += last
}
return sum
}
func Part2(secrets []int) int {
var wg sync.WaitGroup
rewards := SharedStore{Store: make(map[string]int)}
for _, secret := range secrets {
wg.Add(1)
go func(secret int) {
defer wg.Done()
iter := secretIterator(secret, 2000)
previousPrice := secret % 10
buyer := make(map[string]int)
var changes []int
for secret, ok := iter(); ok; secret, ok = iter() {
currentPrice := secret % 10
change := currentPrice - previousPrice
previousPrice = currentPrice
changes = append(changes, change)
if len(changes) > 4 {
changes = changes[1:]
}
if len(changes) == 4 {
key := ""
for _, change := range changes {
key += strconv.Itoa(change) + ","
}
if _, ok := buyer[key]; !ok {
buyer[key] = currentPrice
}
}
}
rewards.Lock.Lock()
defer rewards.Lock.Unlock()
for key, reward := range buyer {
rewards.Store[key] += reward
}
}(secret)
}
wg.Wait()
max := 0
for _, reward := range rewards.Store {
if reward > max {
max = reward
}
}
return max
}
func Run(filename string) (interface{}, interface{}) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
var secrets []int
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
number, err := strconv.Atoi(line)
if err != nil {
panic(err)
}
secrets = append(secrets, number)
}
if err := scanner.Err(); err != nil {
panic(err)
}
part1 := Part1(secrets)
part2 := Part2(secrets)
return part1, part2
}

34
2024/day22/day22_test.go Executable file
View file

@ -0,0 +1,34 @@
package day22
import (
"os"
"testing"
)
type TestCase struct {
FileName string
Part1 interface{}
Part2 interface{}
}
func TestDay22(t *testing.T) {
tests := []TestCase{
{"test.txt", 37990510, 23},
{"input.txt", 19241711734, 2058},
}
for _, test := range tests {
if _, err := os.Stat(test.FileName); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", test.FileName)
}
part1, part2 := Run(test.FileName)
if test.Part1 != nil && part1 != test.Part1 {
t.Fatalf("%s: unexpected part1:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part1, part1)
}
if test.Part2 != nil && part2 != test.Part2 {
t.Fatalf("%s: unexpected part2:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part2, part2)
}
}
}

2256
2024/day22/input.txt Executable file

File diff suppressed because it is too large Load diff

4
2024/day22/test.txt Executable file
View file

@ -0,0 +1,4 @@
1
2
3
2024