diff --git a/day-14/two.go b/day-14/two.go index ccf1a8b..3cc4051 100644 --- a/day-14/two.go +++ b/day-14/two.go @@ -12,26 +12,28 @@ func cycleOnce(image img) { } // cycleMany cycles a single image for a given number of iterations -// it also caches the index of the iteration for each image +// it caches seen images as well as their location in the period +// finally it copies the cached image with idx matching the interval to image.raw func cycleMany(image img, iterations int) { - cache := make(map[string]int) + cachedIndexes := make(map[string]int) + cachedImages := make(map[int][]string) i, start := 0, 0 for ; i < iterations; i++ { cycleOnce(image) - if idx, ok := cache[image.String()]; ok { // we found first repeated image + if idx, ok := cachedIndexes[image.String()]; ok { // we found first repeated image start = idx i++ break } - cache[image.String()] = i + 1 - } - period := i - start // length of a full period - remaining := (iterations - i - 1) % period // number of cycles left in current period - for j := 0; j < remaining; j++ { - cycleOnce(image) // rotate to the final image in the period + cachedIndexes[image.String()] = i + 1 + cachedImages[i+1] = make([]string, len(image.raw)) + copy(cachedImages[i+1], image.raw) } + + period := i - start // length of a full period + copy(image.raw, cachedImages[start+((iterations-i-1)%period)]) // copy cachedImage into image.raw } // two returns the load of all boulders after 1000000000 cycles