diff --git a/2024/aoc b/2024/aoc index fb8ca8a..7e07e3a 100755 Binary files a/2024/aoc and b/2024/aoc differ diff --git a/2024/aoc.hpp b/2024/aoc.hpp index 372e484..1f578a3 100644 --- a/2024/aoc.hpp +++ b/2024/aoc.hpp @@ -96,16 +96,24 @@ public: // Access a chunk of tokens for a given line // E.g. Iterate [1,2], [2,3], [3,4] - std::vector> ChunkView(int line, size_t n, size_t gap) { - std::vector v = _tokens[line]; + std::vector> ChunkView(int line, size_t size, size_t stride) + { + const auto& v = _tokens[line]; std::vector> chunks; - for (size_t i = 0; i < v.size() - 1; i += gap) { - chunks.emplace_back(v.begin() + i, - v.begin() + std::min(v.size(), i + n)); + + if (v.empty() || stride == 0) + return chunks; + + for (size_t i = 0; i + size <= v.size(); i += stride) + { + std::cout << "max " << i + size << " tokens " << v.size() << " index " << i << " size " << size << " stride " << stride << std::endl; + chunks.emplace_back(v.begin() + i, v.begin() + i + size); } + return chunks; } + /// Iterate through all lines and their tokens auto begin() const { return _tokens.begin(); } auto end() const { return _tokens.end(); } diff --git a/2024/day2.hpp b/2024/day2.hpp index 16288b1..71c7796 100644 --- a/2024/day2.hpp +++ b/2024/day2.hpp @@ -7,50 +7,80 @@ public: ~Day02() {} int Day() override {return 2;} + bool isSafe(const std::vector& levels) + { + if (levels.size() < 2) + return true; + + int dir = (levels[1] - levels[0] > 0) ? 1 : -1; + + for (size_t i = 1; i < levels.size(); ++i) + { + int diff = levels[i] - levels[i - 1]; + + if (diff == 0) + return false; + if (std::abs(diff) > 3) + return false; + if ((diff > 0 ? 1 : -1) != dir) + return false; + } + + return true; + } + + bool isSafeWithDampener(const std::vector& levels) + { + // Already safe + if (isSafe(levels)) + return true; + + // BRUTE FORCE + for (size_t i = 0; i < levels.size(); ++i) + { + std::vector copy = levels; + copy.erase(copy.begin() + i); + if (isSafe(copy)) + return true; + } + + return false; + } + int PartOne(File& f) override { f.SplitBy(" "); - int result_bad = 0; + int safe = 0; - for (int i = 0; i < f.Lines().size(); i++) + for (int i = 0; i < f.Lines().size(); ++i) { - bool lastDirection; - bool first = true; - for (const auto& tokenPair : f.ChunkView(i, 2, 1)) - { - int token = std::atoi(tokenPair[0].Data.c_str()); - int nextToken = std::atoi(tokenPair[1].Data.c_str()); + std::vector nums; + for (auto& token : f.TokensForLine(i)) + nums.push_back(std::atoi(token.Data.c_str())); - int diff = token - nextToken; - bool direction = diff > 0; - - if (first) - { - lastDirection = direction; - first = false; - } - - if (std::abs(diff) > 3 - || token == nextToken - || direction != lastDirection) - { - result_bad++; - break; - } - - lastDirection = direction; - first = false; - } + if (isSafe(nums)) + safe++; } - int result = f.Lines().size() - result_bad; - - return result; + return safe; } - int PartTwo(File&) override + int PartTwo(File& f) override { + int safe = 0; + + for (int i = 0; i < f.Lines().size(); ++i) + { + std::vector nums; + for (auto& token : f.TokensForLine(i)) + nums.push_back(std::atoi(token.Data.c_str())); + + if (isSafeWithDampener(nums)) + safe++; + } + + return safe; } };