This commit is contained in:
Feiko Wielsma 2025-12-06 20:36:52 +00:00
parent 840f236c60
commit 43448aaeb6
9 changed files with 1434 additions and 89 deletions

View file

@ -13,8 +13,20 @@ RUN apt-get update \
python3 \ python3 \
python3-pip \ python3-pip \
ca-certificates \ ca-certificates \
curl \
wget \
tmux \
ripgrep \
fd-find \
unzip \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN curl -LO https://github.com/neovim/neovim/releases/download/stable/nvim-linux-x86_64.tar.gz \
&& rm -rf /opt/nvim \
&& tar -C /opt -xzf nvim-linux-x86_64.tar.gz \
&& ln -sf /opt/nvim-linux-x86_64/bin/nvim /usr/local/bin/nvim \
&& rm nvim-linux-x86_64.tar.gz
# Create workspace folder (VS Code devcontainer convention) # Create workspace folder (VS Code devcontainer convention)
ARG WORKSPACE_FOLDER=/workspaces/aoc25 ARG WORKSPACE_FOLDER=/workspaces/aoc25
RUN mkdir -p ${WORKSPACE_FOLDER} && chown -R root:root ${WORKSPACE_FOLDER} RUN mkdir -p ${WORKSPACE_FOLDER} && chown -R root:root ${WORKSPACE_FOLDER}

View file

@ -14,7 +14,7 @@
"ms-vscode.cpptools", "ms-vscode.cpptools",
"ms-vscode.cmake-tools", "ms-vscode.cmake-tools",
"llvm-vs-code-extensions.vscode-clangd", "llvm-vs-code-extensions.vscode-clangd",
"xaver.clang-format" "vadimcn.vscode-lldb"
], ],
"postCreateCommand": "cmake -S . -B build || true" "postCreateCommand": "cmake -S . -B build || true"
} }

View file

@ -38,4 +38,5 @@ add_subdirectory(day1)
add_subdirectory(day2) add_subdirectory(day2)
add_subdirectory(day3) add_subdirectory(day3)
add_subdirectory(day4) add_subdirectory(day4)
add_subdirectory(day5)

View file

@ -1,16 +1,13 @@
#include <iostream> #include <algorithm>
#include <fstream>
#include <string>
#include <string_view>
#include <vector>
#include <expected> #include <expected>
#include <fstream>
#include <iostream>
#include <print> #include <print>
#include <ranges> #include <ranges>
#include <array> #include <string>
#include <map> #include <string_view>
#include <numeric> #include <unordered_map>
#include <functional> #include <vector>
#include <algorithm>
struct IDRange { struct IDRange {
long leftRange; long leftRange;
@ -39,7 +36,6 @@ auto parseRanges(const std::string& filename) -> std::expected<std::vector<IDRan
return std::move(idRanges); return std::move(idRanges);
} }
auto countDoubles(const std::vector<IDRange> &idRanges) { auto countDoubles(const std::vector<IDRange> &idRanges) {
long doubles{}; long doubles{};
for (const auto &rng : idRanges) { for (const auto &rng : idRanges) {
@ -64,14 +60,11 @@ auto countDoubles(const std::vector<IDRange>& idRanges) {
return doubles; return doubles;
} }
auto calculatePossibleSplits(int length) -> std::vector<int> { auto calculatePossibleSplits(int length) -> std::vector<int> {
// std::println("Possible ways to split a str of length {}: ", length); // std::println("Possible ways to split a str of length {}: ", length);
std::vector<int> returnVec{}; std::vector<int> returnVec{};
for (auto toCheck : std::views::iota(2, length + 1)) { for (auto toCheck : std::views::iota(2, length + 1)) {
if(length % toCheck == 0) if (length % toCheck == 0) {
{
// std::println("{}", toCheck); // std::println("{}", toCheck);
returnVec.push_back(toCheck); returnVec.push_back(toCheck);
} }
@ -96,10 +89,9 @@ auto countRepeats(const std::vector<IDRange>& idRanges) {
auto str_len = str_version.size(); auto str_len = str_version.size();
// std::print("Checking {}. Length: {} ", str_version, str_version.size()); // std::print("Checking {}. Length: {} ", str_version, str_version.size());
std::vector<int> numsToCheck = getPossibleSplits(str_len); const std::vector<int> &numsToCheck = getPossibleSplits(str_len);
// std::println("Possible splits: {}", numsToCheck); // std::println("Possible splits: {}", numsToCheck);
for (int checkNum : numsToCheck) for (int checkNum : numsToCheck) {
{
// std::print("Splitting in {}: ", checkNum); // std::print("Splitting in {}: ", checkNum);
std::vector<std::string_view> splits(checkNum); std::vector<std::string_view> splits(checkNum);
for (auto toCheck : std::views::iota(0, checkNum)) { for (auto toCheck : std::views::iota(0, checkNum)) {
@ -125,27 +117,23 @@ auto countRepeats(const std::vector<IDRange>& idRanges) {
auto main() -> int { auto main() -> int {
auto testCase = parseRanges("test_input"); auto testCase = parseRanges("test_input");
if (testCase) { if (testCase) {
auto testResult = countDoubles(*testCase); auto testResult = countDoubles(*testCase);
auto testResultP2 = countRepeats(*testCase); auto testResultP2 = countRepeats(*testCase);
std::println("P1 Testcase result: {}", testResult); std::println("P1 Testcase result: {}", testResult);
std::println("P2 Testcase result: {}", testResultP2); std::println("P2 Testcase result: {}", testResultP2);
} } else {
else{
std::print("{}\n", testCase.error()); std::print("{}\n", testCase.error());
} }
auto realRanges = parseRanges("puzzle_input"); auto realRanges = parseRanges("puzzle_input");
if (realRanges) { if (realRanges) {
// auto realResult = countDoubles(*realRanges); // auto realResult = countDoubles(*realRanges);
auto realResultP2 = countRepeats(*realRanges); auto realResultP2 = countRepeats(*realRanges);
// std::println("P1 Real result: {}", realResult); // std::println("P1 Real result: {}", realResult);
std::println("P2 Real result: {}", realResultP2); std::println("P2 Real result: {}", realResultP2);
} } else {
else{
std::print("{}\n", realRanges.error()); std::print("{}\n", realRanges.error());
} }

View file

@ -19,7 +19,6 @@ struct Diagram {
auto grid() { return GridView(data.data(), height, width); } auto grid() { return GridView(data.data(), height, width); }
}; };
namespace {
auto printMap(Diagram &diagram) { auto printMap(Diagram &diagram) {
auto grid = diagram.grid(); auto grid = diagram.grid();
for (auto row = 0UZ; row != grid.extent(0); row++) { for (auto row = 0UZ; row != grid.extent(0); row++) {
@ -137,7 +136,7 @@ auto moveMoveablePaper(Diagram &diagram) -> long {
return totalPaperRemoved; return totalPaperRemoved;
} }
} // namespace
auto main() -> int { auto main() -> int {
auto testCase = parseMap("test_input"); auto testCase = parseMap("test_input");
if (testCase) { if (testCase) {

2
day5/CMakeLists.txt Normal file
View file

@ -0,0 +1,2 @@
# Use top-level helper to add the target and copy input files
aoc_add_day(day5 "${CMAKE_CURRENT_SOURCE_DIR}" main.cpp)

144
day5/main.cpp Normal file
View file

@ -0,0 +1,144 @@
#include <algorithm>
#include <array>
#include <cstddef>
#include <expected>
#include <fstream>
#include <iostream>
#include <list>
#include <mdspan>
#include <print>
#include <ranges>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
// struct FreshRange {
// long long left;
// long long right;
// };
using FreshRange = std::pair<long long, long long>;
struct PuzzleInput {
std::vector<FreshRange> freshRanges;
std::vector<long long> ingredients;
};
static auto parseInput(const std::string &filename) -> std::expected<PuzzleInput, std::string> {
std::ifstream inputF{filename};
if (!inputF) {
return std::unexpected{"Some file open error.\n"};
}
PuzzleInput puzzleInput{};
std::string puzzleLine{};
while (std::getline(inputF, puzzleLine)) {
if (puzzleLine.empty()) {
std::println("Empty string");
break;
}
auto subParts = std::ranges::to<std::vector<std::string>>(std::views::split(puzzleLine, '-'));
puzzleInput.freshRanges.emplace_back(std::stoll(subParts[0]), std::stoll(subParts[1]));
std::println("Range: {}", subParts);
}
while (std::getline(inputF, puzzleLine)) {
// std::println("Ingredient: {}", puzzleLine);
puzzleInput.ingredients.emplace_back(std::stoll(puzzleLine));
}
// std::println("Ranges: {}\nIngredients: {}", puzzleInput.ingredients, puzzleInput.ingredients);
return std::move(puzzleInput);
}
static auto countFreshIngredients(const PuzzleInput &puzzleInput) -> long long {
const auto &freshRanges = puzzleInput.freshRanges;
const auto &ingredients = puzzleInput.ingredients;
long long totalFresh{};
std::println("Ranges: {}\nIngredients: {}", ingredients, ingredients);
for (const auto ingredient : ingredients) {
std::println("Checking {}", ingredient);
for (const auto &range : freshRanges) {
if (ingredient >= range.first && ingredient <= range.second) {
std::println("{} fits in range: {}:{}", ingredient, range.first, range.second);
totalFresh += 1;
break;
}
}
}
return totalFresh;
}
static long long countAll(const std::ranges::range auto &ranges) {
std::println("Final count:\n\n");
long long bigNum{};
for (const auto &range : ranges) {
std::println("{}:{}", range.first, range.second);
if (range == FreshRange(-1, -1)) {
continue;
}
bigNum += range.second - range.first + 1;
}
return bigNum;
}
static auto countFreshIngredientsRange(std::vector<FreshRange> &ranges) -> long long {
std::ranges::sort(ranges);
std::list<FreshRange> rangeList;
rangeList.assign_range(ranges);
auto cur = rangeList.begin();
while (true) {
auto next = std::next(cur);
std::println("Starting with {}", *cur);
if (next == rangeList.end()) { // No need to compare against the end
break;
}
if (cur->second >= next->first) {
std::println("\t Merging! {}", *next);
cur->second = std::max(cur->second, next->second);
rangeList.erase(next);
} else {
cur++;
}
}
return countAll(rangeList);
}
auto main() -> int {
auto testCase = parseInput("test_input");
if (testCase) {
// auto testResult = countFreshIngredients(*testCase);
// std::println("P1 Testcase result: {}", testResult);
auto testResultP2 = countFreshIngredientsRange((*testCase).freshRanges);
std::println("P2 Testcase result: {}", testResultP2);
} else {
std::print("{}\n", testCase.error());
}
auto realPuzzle = parseInput("puzzle_input");
if (realPuzzle) {
// auto realResult = countFreshIngredients(*realPuzzle);
// std::println("P1 Real result: {}", realResult);
auto realResultP2 = countFreshIngredientsRange((*realPuzzle).freshRanges);
std::println("P2 Real result: {}", realResultP2);
} else {
std::print("{}\n", realPuzzle.error());
}
return 0;
}

1187
day5/puzzle_input Normal file

File diff suppressed because it is too large Load diff

12
day5/test_input Normal file
View file

@ -0,0 +1,12 @@
3-5
10-14
10-13
16-20
12-18
1
5
8
11
17
32