Added all code for day 22
This commit is contained in:
parent
0023a94368
commit
f4e07115c7
5 changed files with 2430 additions and 0 deletions
|
|
@ -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
134
2024/day22/day22.go
Executable 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
34
2024/day22/day22_test.go
Executable 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
2256
2024/day22/input.txt
Executable file
File diff suppressed because it is too large
Load diff
4
2024/day22/test.txt
Executable file
4
2024/day22/test.txt
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
2024
|
||||
Loading…
Add table
Add a link
Reference in a new issue