advent2024

Advent of Code 2024
git clone git://bsandro.tech/advent2024
Log | Files | Refs

commit a050f700e90dfd22421196e357639af4dc8a52a0
parent 1ef73fadbacf267c38ca06b63edab52da8bb4366
Author: bsandro <email@bsandro.tech>
Date:   Thu, 12 Dec 2024 02:23:39 +0200

Day 11 p2

Diffstat:
Mday11/Makefile | 5++++-
Mday11/main.cpp | 88++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mday11/test2.txt | 2+-
Cday11/test2.txt -> day11/test3.txt | 0
4 files changed, 79 insertions(+), 16 deletions(-)

diff --git a/day11/Makefile b/day11/Makefile @@ -2,7 +2,7 @@ NAME=$(shell basename ${PWD}) SRC=$(wildcard *.cpp) DEPS:=$(wildcard *.hpp) OBJ:=$(SRC:.cpp=.o) -CXXFLAGS=-O2 -std=c++23 -Werror -Wall -Wextra -I. -I../include +CXXFLAGS=-Os -std=c++23 -Werror -Wall -Wextra -I. -I../include LDFLAGS=-lstdc++ all: $(NAME) @@ -26,3 +26,6 @@ test1: $(NAME) test2: $(NAME) @./$(NAME) test2.txt + +test3: $(NAME) + @./$(NAME) test3.txt diff --git a/day11/main.cpp b/day11/main.cpp @@ -6,6 +6,7 @@ #include <cstdio> #include <tuple> #include <algorithm> +#include <map> #include <thread> #include <future> #include "utils.hpp" @@ -25,19 +26,80 @@ T read_file(const std::string &path) { return buf; } -void blink(Data &stones) { - for (auto it=stones.begin(); it!=stones.end(); ++it) { - std::string s = std::to_string(*it); - if (*it==0) { - *it = 1; +typedef std::tuple<int, uint64_t, uint64_t> Memo; +typedef std::map<uint64_t, Memo> Cache; +typedef std::map<uint64_t, std::vector<std::pair<int, uint64_t>>> GenCache; + +uint64_t findGenCache(GenCache &cache, uint64_t stone, int num) { + uint64_t val = 0; + for (auto v:cache[stone]) { + auto [blinks, sum] = v; + if (blinks==num) { + val=sum; + break; + } + } + return val; +} + +uint64_t calc(uint64_t stone, int num, Cache &cache, GenCache &genCache) { + if (num<=0) return 1; + if (genCache.contains(stone)) { + uint64_t v = findGenCache(genCache, stone, num); + if (v!=0) return v; + } + if (cache.contains(stone)) { + auto [blinks, s1, s2] = cache[stone]; + if (blinks>num) return 1; + else if (s1==0) return 1; + uint64_t res = calc(s1, num-blinks, cache, genCache)+calc(s2, num-blinks, cache, genCache); + genCache[stone].push_back(std::make_pair(num, res)); + return res; + } + + uint64_t derived = stone; + for (int i=1; i<=num; ++i) { + std::string s = std::to_string(derived); + if (derived==0) { + derived = 1; } else if (s.size()%2==0) { uint64_t n1 = std::stoi(s.substr(0, s.size()/2)); uint64_t n2 = std::stoi(s.substr(s.size()/2, s.size())); - *it = n2; - it = stones.insert(it, n1); - it++; + cache[stone] = std::make_tuple(i, n1, n2); + return calc(n1, num-i, cache, genCache)+calc(n2, num-i, cache, genCache); } else { - *it *= 2024; + derived *= 2024; + } + } + genCache[stone].push_back(std::make_pair(num, 1)); + return 1; +} + +uint64_t blink3(Data &stones, int num) { + Cache cache; + GenCache genCache; + uint64_t result = 0; + for (uint64_t s:stones) { + result += calc(s, num, cache, genCache); + } + return result; +} + +void blink(Data &stones, int num) { + for (int i=0; i<num; ++i) { + for (auto it=stones.begin(); it!=stones.end(); ++it) { + std::string s = std::to_string(*it); + if (*it==0) { + *it = 1; + } else if (s.size()%2==0) { + uint64_t n1 = std::stoi(s.substr(0, s.size()/2)); + uint64_t n2 = std::stoi(s.substr(s.size()/2, s.size())); + *it = n2; + it = stones.insert(it, n1); + it++; + } else { + *it *= 2024; + } } } } @@ -45,13 +107,11 @@ void blink(Data &stones) { void blink2(uint64_t start, int num, std::promise<uint64_t> &&result) { Data stones; stones.push_back(start); - for (int i=0; i<num; ++i) { - blink(stones); - } + blink(stones, num); result.set_value(stones.size()); } -void printStones(const Data &stones) { +[[ maybe_unused ]] void printStones(const Data &stones) { for (auto n:stones) { std::cout << "[" << n << "]"; } @@ -76,7 +136,7 @@ int64_t part1(Data input [[ maybe_unused ]]) { } int64_t part2(Data input [[ maybe_unused ]]) { - return 0; + return blink3(input, 75); } int main(int argc, char **argv) { diff --git a/day11/test2.txt b/day11/test2.txt @@ -1 +1 @@ -125 17 +0 diff --git a/day11/test2.txt b/day11/test3.txt