Compare commits

..

No commits in common. "c7118f49afe1c4506f70d09ea4790f07adfdd1d5" and "3543f8a117e4639ccab272b51ffec221904b5777" have entirely different histories.

7 changed files with 8 additions and 314 deletions

View file

@ -1,79 +0,0 @@
package main
import (
"fmt"
"hash/fnv"
"strconv"
"sync"
"git.mstar.dev/mstar/goutils/other"
// "github.com/patrickmn/go-cache"
)
// var valCache = cache.New(time.Minute, time.Minute*2)
var valCacheMap = map[uint64]uint64{}
var mLock sync.RWMutex
func hash(val uint64, iter, maxIter int) uint64 {
h := fnv.New64a()
_, err := h.Write([]byte(fmt.Sprintf("%d.%d.%d", val, iter, maxIter)))
if err != nil {
panic(err)
}
return h.Sum64()
}
func fromCache(val uint64, iteration, maxIter int) (uint64, bool) {
mLock.RLock()
pv, ok := valCacheMap[hash(val, iteration, maxIter)]
mLock.RUnlock()
// v, ok := valCache.Get(strconv.FormatUint(hash(val, iteration, maxIter), 10))
// if !ok {
// return 0, false
// }
// pv, ok := v.(uint64)
return pv, ok
}
func intoCache(val uint64, iteration, maxIter int, result uint64) {
mLock.Lock()
valCacheMap[hash(val, iteration, maxIter)] = result
mLock.Unlock()
// valCache.Set(strconv.FormatUint(hash(val, iteration, maxIter), 10), result, -1)
}
func Advance(val uint64, iteration int, maxIter int) (out uint64) {
cacheVal, ok := fromCache(val, iteration, maxIter)
if ok {
return cacheVal
}
defer func() {
if _, ok := fromCache(val, iteration, maxIter); !ok {
intoCache(val, iteration, maxIter, out)
}
}()
// fmt.Printf("Iteration %d with val %d\n", iteration, val)
if iteration == maxIter {
// fmt.Println("1")
out = 1
return
}
if val == 0 {
// fmt.Println("0")
out = Advance(1, iteration+1, maxIter)
return
}
if len(strconv.FormatUint(val, 10))%2 == 0 {
// fmt.Println("Split")
str := strconv.FormatUint(val, 10)
// fmt.Println("format")
left := other.Must(strconv.ParseUint(string([]rune(str)[:len(str)/2]), 10, 64))
right := other.Must(strconv.ParseUint(string([]rune(str)[len(str)/2:]), 10, 64))
// fmt.Printf("l: %d, r: %d\n", left, right)
out = Advance(left, iteration+1, maxIter) + Advance(right, iteration+1, maxIter)
return
}
out = Advance(val*2024, iteration+1, maxIter)
return out
}

View file

@ -1 +0,0 @@
28 4 3179 96938 0 6617406 490 816207

View file

@ -1,185 +0,0 @@
package main
import (
"fmt"
"strconv"
"strings"
"git.mstar.dev/mstar/aoc24/util"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/goutils/sliceutils"
)
type TreeNode struct {
Left, Right *TreeNode
Value uint64
IsLeaf bool
}
func lineToNumbers(line string) []uint64 {
return sliceutils.Map(
strings.Split(line, " "),
func(t string) uint64 { return other.Must(strconv.ParseUint(t, 10, 64)) },
)
}
func numbersIntoTree(numbers []uint64) *TreeNode {
switch len(numbers) {
case 1:
return &TreeNode{
Left: &TreeNode{
Left: nil,
Right: nil,
Value: numbers[0],
IsLeaf: true,
},
Right: nil,
Value: 0,
IsLeaf: false,
}
case 2:
return &TreeNode{
Left: &TreeNode{
Left: nil,
Right: nil,
Value: numbers[0],
IsLeaf: true,
},
Right: &TreeNode{
Left: nil,
Right: nil,
Value: numbers[1],
IsLeaf: true,
},
Value: 0,
IsLeaf: false,
}
default:
l, r := splitListIntoTwo(numbers)
return &TreeNode{
Left: numbersIntoTree(l),
Right: numbersIntoTree(r),
Value: 0,
IsLeaf: false,
}
}
}
func splitListIntoTwo[S ~[]T, T any](s S) (S, S) {
middle := len(s) / 2
left := S{}
right := S{}
for i, v := range s {
if i < middle {
left = append(left, v)
} else {
right = append(right, v)
}
}
return left, right
}
func (n *TreeNode) Advance() {
if n.IsLeaf {
// 1. 0 -> 1
// 2. len("num") % 2 == 0 -> num[len("num")/2:], num[:len("num")/2]
// 2424 -> 24, 24; 435892 -> 435, 892
// 3. x -> x * 2024
switch {
case n.Value == 0:
n.Value = 1
case len(strconv.FormatUint(n.Value, 10))%2 == 0:
str := strconv.FormatUint(n.Value, 10)
left := string([]rune(str)[:len(str)/2])
right := string([]rune(str)[len(str)/2:])
n.IsLeaf = false
n.Left = &TreeNode{
Left: nil,
Right: nil,
Value: other.Must(strconv.ParseUint(left, 10, 64)),
IsLeaf: true,
}
n.Right = &TreeNode{
Left: nil,
Right: nil,
Value: other.Must(strconv.ParseUint(right, 10, 64)),
IsLeaf: true,
}
default:
n.Value *= 2024
}
} else {
if n.Left != nil {
n.Left.Advance()
}
if n.Right != nil {
n.Right.Advance()
}
}
}
func (n *TreeNode) String() string {
if n.IsLeaf {
return fmt.Sprint(n.Value)
} else {
if n.Right != nil {
return fmt.Sprintf("%s %s", n.Left, n.Right)
} else {
return fmt.Sprint(n.Left)
}
}
}
func (n *TreeNode) Count() uint64 {
if n.IsLeaf {
return 1
} else {
if n.Right != nil {
return n.Left.Count() + n.Right.Count()
} else {
return n.Left.Count()
}
}
}
func main() {
nums := lineToNumbers(strings.TrimSpace(string(util.LoadFileFromArgs())))
tree := numbersIntoTree(nums)
// fmt.Printf("%#v\n", tree.Right)
for range 25 {
tree.Advance()
}
fmt.Printf("Task 1: %d\n", tree.Count())
var accCheck uint64 = 0
for _, num := range nums {
accCheck += Advance(num, 0, 25)
}
fmt.Printf("Check 1: %d\n", accCheck)
// for range 50 {
// tree.Advance()
// }
// fmt.Printf("Task 2: %d\n", tree.Count())
// resetCache()
var acc uint64 = 0
for _, num := range nums {
acc += Advance(num, 0, 75)
}
// addChan := make(chan uint64, 1)
// wg := sync.WaitGroup{}
// go func() {
// for v := range addChan {
// acc += v
// }
// }()
// for _, num := range nums {
// wg.Add(1)
// go func() {
// addChan <- Advance(num, 0, 75)
// wg.Done()
// }()
// }
// wg.Wait()
// close(addChan)
fmt.Printf("Task 2: %d\n", acc)
}

View file

@ -1,48 +0,0 @@
package main
import (
"fmt"
"strconv"
"git.mstar.dev/mstar/goutils/other"
"github.com/Skarlso/cache"
)
var stoneCache = cache.New[uint64]()
// Doesn't work, the cache thing can't handle recursion
func AdvanceBroken(val uint64, iteration int, maxIter int) cache.Cacheable[uint64] {
return func() uint64 {
fmt.Printf("Iteration %d with val %d\n", iteration, val)
if iteration == maxIter {
fmt.Println("1")
return 1
}
if val == 0 {
fmt.Println("0")
return stoneCache.WithCache(
AdvanceBroken(1, iteration+1, maxIter),
[]any{1, iteration + 1, maxIter},
)
}
if len(strconv.FormatUint(val, 10))%2 == 0 {
fmt.Println("Split")
str := strconv.FormatUint(val, 10)
fmt.Println("format")
left := other.Must(strconv.ParseUint(string([]rune(str)[:len(str)/2]), 10, 64))
right := other.Must(strconv.ParseUint(string([]rune(str)[len(str)/2:]), 10, 64))
fmt.Printf("l: %d, r: %d\n", left, right)
return stoneCache.WithCache(
AdvanceBroken(left, iteration+1, maxIter),
[]any{left, iteration + 1, maxIter},
) + stoneCache.WithCache(
AdvanceBroken(right, iteration+1, maxIter),
[]any{right, iteration + 1, maxIter},
)
}
return stoneCache.WithCache(
AdvanceBroken(val*2024, iteration+1, maxIter),
[]any{val * 2024, iteration + 1, maxIter},
)
}
}

View file

@ -1 +0,0 @@
125 17

2
go.mod
View file

@ -3,3 +3,5 @@ module git.mstar.dev/mstar/aoc24
go 1.23.3 go 1.23.3
require git.mstar.dev/mstar/goutils v1.5.4 require git.mstar.dev/mstar/goutils v1.5.4
require github.com/BooleanCat/go-functional/v2 v2.3.0 // indirect

6
go.sum
View file

@ -1,2 +1,8 @@
git.mstar.dev/mstar/goutils v1.5.3 h1:Wqa8H8EWnc9IJmzsi6qeVqwYHPvWiDhG/b9WtZr0Nos=
git.mstar.dev/mstar/goutils v1.5.3/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.5.4 h1:l/4oQe/fBk9zyXplQkGXbmQndnm0aRdHuy4wgQfNrFo= git.mstar.dev/mstar/goutils v1.5.4 h1:l/4oQe/fBk9zyXplQkGXbmQndnm0aRdHuy4wgQfNrFo=
git.mstar.dev/mstar/goutils v1.5.4/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA= git.mstar.dev/mstar/goutils v1.5.4/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
github.com/BooleanCat/go-functional/v2 v2.3.0 h1:mwVrUa4MSKQNs/N4EPy0fadRLyzP+eoc0NbnzWHEzLM=
github.com/BooleanCat/go-functional/v2 v2.3.0/go.mod h1:IpUUAXAc9CiWDb+YDXkJyyUhtOVqDtyICDRg/de1IaQ=
gitlab.com/mstarongitlab/goutils v1.5.1 h1:UlQL90DctJ7QbfJ5NOPheMK3PdFt6sBIjXR3fJpd3Ms=
gitlab.com/mstarongitlab/goutils v1.5.1/go.mod h1:f71xLeTv05GHiRHKkgDRXfxOPRkjXNteXqLZyg02xhs=