2024 D2P2 (I hate this)
This commit is contained in:
18
2024/aoc.hpp
18
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<std::vector<FileFragment>> ChunkView(int line, size_t n, size_t gap) {
|
||||
std::vector<FileFragment> v = _tokens[line];
|
||||
std::vector<std::vector<FileFragment>> ChunkView(int line, size_t size, size_t stride)
|
||||
{
|
||||
const auto& v = _tokens[line];
|
||||
std::vector<std::vector<FileFragment>> 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(); }
|
||||
|
||||
@@ -7,50 +7,80 @@ public:
|
||||
~Day02() {}
|
||||
int Day() override {return 2;}
|
||||
|
||||
bool isSafe(const std::vector<int>& 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<int>& levels)
|
||||
{
|
||||
// Already safe
|
||||
if (isSafe(levels))
|
||||
return true;
|
||||
|
||||
// BRUTE FORCE
|
||||
for (size_t i = 0; i < levels.size(); ++i)
|
||||
{
|
||||
std::vector<int> 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<int> 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<int> nums;
|
||||
for (auto& token : f.TokensForLine(i))
|
||||
nums.push_back(std::atoi(token.Data.c_str()));
|
||||
|
||||
if (isSafeWithDampener(nums))
|
||||
safe++;
|
||||
}
|
||||
|
||||
return safe;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user