Compare commits

36 Commits

Author SHA1 Message Date
1079b2536c 2025 day06 p2 2025-12-14 22:04:04 +01:00
8062f9a537 2025 day 05 p2 2025-12-14 20:43:34 +01:00
ed04586b1d 2025 day 07 p1 2025-12-14 18:43:39 +01:00
11ed18a199 2025 day 06 p1 2025-12-14 17:39:21 +01:00
65f6175bc9 2025 day 05 p1 2025-12-14 14:37:38 +01:00
60e78353d7 2025 day 4 p1 2025-12-14 12:43:52 +01:00
b90bcb0c9d 2025 day 3 p1 2025-12-14 08:00:30 +01:00
7fb1f4f778 2025 day 2 p1 2025-12-11 13:57:49 +01:00
abecf6cfb7 Add function in cmake to create targets 2025-12-09 16:12:19 +01:00
432a5b1f7c force solution
Change-Id: I1421c6279597b9cb040dfcafb6984a3730503d10
2025-12-09 10:36:14 +01:00
14ec3ca2da 2025D01P1: done 2025-12-09 04:20:27 +01:00
d106e7541d Prepare day01 2025
Change-Id: Id3c46f5f552db5a0ba200dedc1ea4e4434932982
2025-12-08 11:43:38 +01:00
49d82b8f90 prep for 2025 2025-12-03 16:26:25 +01:00
c238e9b4fb aoc: 2024 bk 2025-12-02 09:13:23 +01:00
da8a4cc5de aoc24: day17 cpu 2024-12-18 21:53:42 +01:00
5810fe22e9 aoc24: day17 started 2024-12-17 18:01:49 +01:00
5c7da45fe1 aoc24: day16 create graph 2024-12-16 21:17:17 +01:00
9c840a7c8f aoc24: add day16 2024-12-16 16:43:34 +01:00
1108b8c65b aoc24: day07a complete 2024-12-16 04:03:02 +01:00
7ae660566e aoc24: add day11 2024-12-11 08:08:46 +01:00
521b3dc806 aoc24: add day10 2024-12-10 17:45:40 +01:00
c175b4ebc4 aoc24: day05 filter invalid 2024-12-09 15:16:11 +01:00
ec9028c5f5 aoc24: add day07-08 2024-12-09 02:15:47 +01:00
aaff50eae9 aoc24: day05a add back 2024-12-09 01:30:49 +01:00
57d9bdf0f3 aoc24: day06a complete 2024-12-09 01:27:55 +01:00
a35123500e aoc24: Add README.md 2024-12-09 00:12:55 +01:00
5a02b90f85 aoc24: day04b complete 2024-12-08 23:58:15 +01:00
a1d5d359f2 aoc24: day02b complete 2024-12-08 22:35:49 +01:00
5c692fe727 aoc24: day05a complete 2024-12-06 12:13:39 +01:00
8df8cbb0e4 aoc24: day05a split sections
rules and updates
2024-12-05 16:38:03 +01:00
1c6bbc6cef aoc24: day03b complete 2024-12-03 21:20:47 +01:00
9e68114169 aoc24: day03a complete 2024-12-03 20:56:46 +01:00
c685dcddfb aoc24: day03 tokenizer 2024-12-03 16:43:38 +01:00
616f6bd610 aoc24: day02b not working 2024-12-03 01:49:01 +01:00
242f599c8a aoc24: day02a complete 2024-12-02 21:31:24 +01:00
311ccc0e71 not complete 2024-12-02 17:23:49 +01:00
24 changed files with 1498 additions and 1231 deletions

38
2025/CMakeLists.txt Normal file
View File

@@ -0,0 +1,38 @@
find_package(fmt REQUIRED)
find_package(utf8cpp REQUIRED)
find_package(ctre REQUIRED)
function(add_day_executables)
foreach(src IN LISTS ARGN)
get_filename_component(name "${src}" NAME_WE)
add_executable(${name} "${src}")
target_include_directories(${name} PUBLIC "${PROJECT_SOURCE_DIR}")
target_compile_features(${name} PRIVATE cxx_std_23)
target_link_libraries(${name}
PRIVATE
${PLATFORM_LINK_LIBRARIES}
fmt
utf8cpp
ctre
)
target_compile_definitions(${name} PRIVATE ${PLATFORM_DEFINITIONS})
target_compile_options(${name} PRIVATE ${BASE_OPTIONS})
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES "${src}")
endforeach()
endfunction()
add_day_executables(
"day01.cpp"
"day02.cpp"
"day03.cpp"
"day04.cpp"
"day05.cpp"
"day06.cpp"
"day07.cpp"
)

127
2025/day01.cpp Normal file
View File

@@ -0,0 +1,127 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// simple pipe for std::string by value
template <typename F>
auto operator|(std::string s, F&& f) -> decltype(auto) {
return std::forward<F>(f)(std::move(s));
}
auto ltrim(std::string s) -> std::string {
s.erase(
std::begin(s),
std::find_if(s.begin(), s.end(), [](char ch) {
return !std::isspace(static_cast<char>(ch));
}));
return s;
}
auto rtrim(std::string s) -> std::string {
s.erase(
std::find_if(s.rbegin(), s.rend(), [](char ch) {
return !std::isspace(static_cast<char>(ch));
}).base(),
s.end());
return s;
}
auto trim(std::string s) -> std::string {
return ltrim(rtrim(std::move(s)));
}
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82
)";
auto map_char_to_rotdir(char c) -> i32 {
switch (c) {
case 'L': return -1;
case 'R':
default: return 1;
}
}
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = str | trim;
auto rot_vec = str | std::views::split("\n"sv) | std::views::transform([](auto const& str) {
return i32(std::stoi(std::string{++std::begin(str), std::end(str)})) * map_char_to_rotdir(*std::begin(str));
}) | std::ranges::to<std::vector>();
i32 start = 50;
i32 zero_cross = 0;
// auto sum = std::ranges::fold_left(rot_vec, 0, [&](auto a, auto t) {
// auto const p = start;
// start = (100 + p - t) % 100;
//
// zero_cross += (std::abs((p - t + 1) % 100) + std::abs(t)) / 100;
//
// fmt::print("pos: {}, next: {}, t: {}\n", p, start, t);
//
// if (start == 0) {
// a += 1;
// }
//
// return a;
// });
auto sum = std::ranges::fold_left(rot_vec, 0, [&](auto a, auto t) {
auto const dir = t < 0 ? -1 : 1;
auto const steps = std::abs(t);
for (i32 i = 0; i < steps; ++i) {
auto next = start + dir;
if (next < 0) next = 99;
next = next % 100;
if (next % 100 == 0)
++zero_cross;
start = next;
}
if (start % 100 == 0) {
++a;
if (zero_cross > 0)
zero_cross -= 1;
}
return a;
});
fmt::print("res: {}, {} sum = {}\n", sum, zero_cross, sum + zero_cross);
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

90
2025/day02.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,
1698522-1698528,446443-446449,38593856-38593862,565653-565659,
824824821-824824827,2121212118-2121212124
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
auto ids_str = str | std::views::split(","sv) | std::views::transform([](auto const& str) {
std::vector<u64> range{};
range.resize(2);
// std::ranges::transform(
// aoc::trim(std::string{std::begin(str), std::end(str)}) | std::views::split("-"sv),
// std::begin(range),
// [](auto const& value) {
// return aoc::trim(std::string{std::begin(value), std::end(value)});
// });
std::ranges::transform(
aoc::trim(std::string{std::begin(str), std::end(str)}) | std::views::split("-"sv),
std::begin(range),
[](auto const& value) {
return u64(std::stoul(aoc::trim(std::string{std::begin(value), std::end(value)})));
});
return range;
}) | std::ranges::to<std::vector>();
auto is_valid_id = [](u64 id) {
auto const str = fmt::format("{}", id);
if (str.size() % 2 != 0) return true;
bool is_invalid = true;
for (usize i = 0; i < str.size() / 2; ++i) {
if (str[i] != str[str.size() / 2 + i]) {
is_invalid = false;
continue;
}
}
return !is_invalid;
};
u64 sum = 0;
for (auto const& id : ids_str) {
u64 const start = id[0];
u64 const end = id[1];
fmt::print("{} -> {}: ", id[0], id[1]);
for (u64 i = start; i <= end; ++i) {
if (!is_valid_id(i)) {
fmt::print("{}, ", i);
sum += i;
}
}
fmt::print("\n");
}
fmt::print("res: {}\n", sum);
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

73
2025/day03.cpp Normal file
View File

@@ -0,0 +1,73 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
987654321111111
811111111111119
234234234234278
818181911112111
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
fmt::print("INPUT\n");
fmt::print("⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼\n");
fmt::print("{}\n", str);
fmt::print("{}\n", std::string(80, '-'));
auto jolts_str = str | std::views::split("\n"sv) | std::views::transform([](auto const& str) {
return aoc::trim(std::string{std::begin(str), std::end(str)});
}) | std::ranges::to<std::vector>();
std::vector<u64> jolts{};
jolts.reserve(jolts_str.size());
for (auto const& jolt : jolts_str) {
u64 largest = 0;
for (usize i = 0; i < jolt.size(); ++i) {
for (usize j = i + 1; j < jolt.size(); ++j) {
auto const value = std::stoull(fmt::format("{}{}", jolt[i], jolt[j]));
if (value > largest) largest = value;
}
}
jolts.push_back(largest);
}
for (auto const& jolt : jolts) {
fmt::print("{}\n", jolt);
}
auto sum = std::ranges::fold_left(jolts, u64(0), [&](auto a, auto v) {
return a + v;
});
fmt::print("res: {}\n", sum);
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

83
2025/day04.cpp Normal file
View File

@@ -0,0 +1,83 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@.
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
fmt::print("INPUT\n");
fmt::print("⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼\n");
fmt::print("{}\n", str);
fmt::print("{}\n", std::string(80, '-'));
auto grid = str | std::views::split("\n"sv) | std::views::transform([](auto const& str) {
return aoc::trim(std::string{std::begin(str), std::end(str)}) |
std::views::transform([](auto const& ch) { return ch; }) |
std::ranges::to<std::vector>();
}) | std::ranges::to<std::vector>();
u64 access = 0;
for (isize i = 0; i < isize(grid.size()); ++i) {
for (isize j = 0; j < isize(grid[i].size()); ++j) {
auto const v = grid[i][j];
if (v == '.') continue;
u64 sum = 0;
if (i - 1 >= 0 && j - 1 >= 0 && grid[i - 1][j - 1] == '@') ++sum;
if (i - 1 >= 0 && grid[i - 1][j] == '@') ++sum;
if (i - 1 >= 0 && j + 1 < isize(grid[i].size()) && grid[i - 1][j + 1] == '@') ++sum;
if (j - 1 >= 0 && grid[i][j - 1] == '@') ++sum;
if (j + 1 < isize(grid[i].size()) && grid[i][j + 1] == '@') ++sum;
if (i + 1 < isize(grid.size()) && j - 1 >= 0 && grid[i + 1][j - 1] == '@') ++sum;
if (i + 1 < isize(grid.size()) && grid[i + 1][j] == '@') ++sum;
if (i + 1 < isize(grid.size()) && j + 1 < isize(grid[i].size()) && grid[i + 1][j + 1] == '@') ++sum;
if (sum < 4) {
// fmt::print("{},{}: {}\n", i, j, sum);
++access;
}
}
}
fmt::print("res: {}\n", access);
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

153
2025/day05.cpp Normal file
View File

@@ -0,0 +1,153 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include <set>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
3-5
10-14
16-20
12-18
1
5
8
11
17
32
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
auto id_spec = str | std::views::split("\r\n\r\n"sv) | std::views::transform([](auto const& str) {
return aoc::trim({std::begin(str), std::end(str)});
}) | std::ranges::to<std::vector>();
if (id_spec.size() < 2) throw std::runtime_error("ID specification is not valid");
auto id_range = id_spec[0] | std::views::split("\n"sv) | std::views::transform([](auto const& str) {
return std::ranges::fold_left(str | std::views::split("-"sv), std::vector<f64>{}, [](auto a, auto const& v) {
a.push_back(std::stod(std::string({std::begin(v), std::end(v)})));
return a;
});
}) | std::ranges::to<std::vector>();
auto ids = id_spec[1] | std::views::split("\n"sv) | std::views::transform([](auto const& str) {
return std::stod(std::string{std::begin(str), std::end(str)});
}) | std::ranges::to<std::vector>();
struct range {
f64 start;
f64 end;
};
// f64 sum = 0;
// for (usize i = 0; i < ids.size(); ++i) {
// auto const id = ids[i];
// bool is_valid = false;
// for (usize j = 0; j < id_range.size(); ++j) {
// auto const a = id_range[j][0];
// auto const b = id_range[j][1];
//
// if (id >= a && id <= b) {
// is_valid = true;
// break;
// }
// }
//
// fmt::print("id: {} is {}\n", id, is_valid ? "valid" : "not valid");
//
// if (is_valid) ++sum;
// }
std::vector<range> range_vec{};
for (usize i = 0; i < id_range.size(); ++i) {
auto const a = id_range[i][0];
auto const b = id_range[i][1];
range_vec.push_back({a, b});
}
std::ranges::sort(range_vec, [](auto a, auto b) {
return a.start < b.start;
});
fmt::print("----------\n");
// for (auto const& r : range_vec) {
// fmt::print("{}-{}\n", r.start, r.end);
// }
//
// fmt::print("----------\n");
std::vector<range> ranges{};
for (usize i = 0; i < range_vec.size(); i += 1) {
auto const& r = range_vec[i];
if (ranges.empty()) {
ranges.push_back(r);
continue;
}
if (ranges.back().start <= r.start && ranges.back().end >= r.end) {
continue;
}
if (ranges.back().end >= r.start) {
ranges.back().end = r.end;
continue;
}
ranges.push_back(r);
}
fmt::print("\n");
f64 sum = 0.0;
for (auto const& r : ranges) {
// fmt::print("{}-{} ", r.start, r.end);
auto const d = (r.end - r.start) + 1;
fmt::print("{}\n", d);
sum += d;
}
fmt::print("res: {}\n", sum);
//
// std::vector<f64> ranges{};
// for (auto const& value : set) ranges.push_back(value);
// set = {};
// std::ranges::sort(ranges);
//
//
// // for (auto const& id : valid_ids) {
// // fmt::print("{} ", id);
// // }
// fmt::print("\n");
//
// fmt::print("res: {}\n", sum);
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

130
2025/day06.cpp Normal file
View File

@@ -0,0 +1,130 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(123 328 51 64
45 64 387 23
6 98 215 314
* + * + )";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
// str = aoc::trim(str);
// fmt::print("INPUT\n");
// fmt::print("⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼\n");
// fmt::print("{}\n", str);
// fmt::print("{}\n", std::string(80, '-'));
auto vec = str | std::views::split("\r\n"sv) | std::views::transform([](auto&& line) {
return line | std::views::split(" "sv)
| std::views::filter([](auto&& tok) { return !std::ranges::empty(tok); })
| std::views::transform([](auto&& tok) {
return aoc::trim(std::string{std::begin(tok), std::end(tok)});
})
| std::ranges::to<std::vector>();
}) | std::ranges::to<std::vector>();
std::vector<std::vector<std::string>> nums{};
std::vector<std::string> ops{};
for (usize i = 0; i < vec.size(); ++i) {
for (usize j = 0; j < vec[i].size(); ++j) {
auto const& value = vec[i][j];
if (nums.size() <= j) nums.push_back({});
if (value == "*" || value == "+") {
ops.push_back(value);
continue;
}
nums[j].push_back(vec[i][j]);
}
}
// fmt::print("{} {}\n", nums.size(), ops.size());
f64 sum = 0.0;
for (usize i = 0; i < nums.size(); ++i) {
auto const& op = ops[i];
f64 row_sum = op == "*" ? 1.0 : 0.0;
for (usize j = 0; j < nums[i].size(); ++j) {
if (op == "*") row_sum *= std::stod(nums[i][j]);
else if (op == "+") row_sum += std::stod(nums[i][j]);
}
// fmt::print("sum: {}\n", row_sum);
sum += row_sum;
}
auto lines = str | std::views::split("\r\n"sv) | std::views::transform([](auto&& line) {
return std::string{std::begin(line), std::end(line)};
}) | std::ranges::to<std::vector>();
// for (usize i = 0; i < lines.size(); ++i) {
// fmt::print("| {} |\n", lines[i]);
// }
for (usize i = 0; i < lines.size(); ++i) {
fmt::print("size: {}\n", lines[i].size());
}
std::vector<std::vector<std::string>> mat{};
auto const w = lines[0].size();
fmt::print("w: {}\n", w);
for (isize j = w - 1; j >= 0; --j) {
std::string tmp{};
if (mat.empty()) mat.push_back({});
for (usize i = 0; i < lines.size() - 1; ++i) {
tmp += lines[i][j];
}
mat.back().push_back(aoc::trim(tmp));
auto const ch = lines[lines.size() - 2][j];
if (ch == '+' || ch == '*') {
mat.push_back({});
continue;
}
}
f64 new_sum = 0.0;
for (usize i = 0; i < mat.size() - 1; ++i) {
auto const& op = ops[mat.size() - 2 - i];
f64 row_sum = op == "*" ? 1.0 : 0.0;
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j].empty()) continue;
fmt::print("{},", aoc::trim(mat[i][j]));
if (op == "*") row_sum *= std::stod(aoc::trim(mat[i][j]));
else if (op == "+") row_sum += std::stod(aoc::trim(mat[i][j]));
}
new_sum += row_sum;
fmt::print("\n");
}
fmt::print("res: {}, {}\n", sum, new_sum);
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

108
2025/day07.cpp Normal file
View File

@@ -0,0 +1,108 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include <tuple>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
.......S.......
...............
.......^.......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
auto mat = str | std::views::split("\n"sv) | std::views::transform([](auto line) {
return line | std::views::split(""sv)
| std::views::transform([](auto tok) {
return std::string{std::begin(tok), std::end(tok)};
})
| std::ranges::to<std::vector>();
}) | std::ranges::to<std::vector>();
struct beam {
usize row;
usize col;
};
std::vector<beam> beams{};
for (usize i = 0; i < mat.size(); ++i) {
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j] == "S") {
beams.push_back({i, j});
break;
}
auto const size = beams.size();
for (usize k = 0; k < size; ++k) {
if (beams[k].row == i - 1 && beams[k].col == j) {
if (mat[i][j] == ".") {
mat[i][j] = "|";
beams[k] = {i, j};
} else if (mat[i][j] == "^") {
beams[k] = {i, j - 1};
beams.push_back({i, j + 1});
mat[i][j - 1] = "|";
mat[i][j + 1] = "|";
}
}
}
}
}
f64 sum = 0.0;
for (usize i = 0; i < mat.size(); ++i) {
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j] == "^") {
if (mat[i - 1][j] == "|") sum += 1;
}
}
}
fmt::print("res: {}\n", sum);
// for (auto const& row : mat) {
// for (auto const& col : row) {
// fmt::print("{}", col);
// }
// fmt::print("\n");
// }
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

112
2025/day08.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include <tuple>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
162,817,812
57,618,57
906,360,560
592,479,940
352,342,300
466,668,158
542,29,236
431,825,988
739,650,466
52,470,668
216,146,977
819,987,18
117,168,530
805,96,715
346,949,466
970,615,88
941,993,340
862,61,35
984,92,344
425,690,689
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
auto mat = str | std::views::split("\n"sv) | std::views::transform([](auto line) {
return line | std::views::split(""sv)
| std::views::transform([](auto tok) {
return std::string{std::begin(tok), std::end(tok)};
})
| std::ranges::to<std::vector>();
}) | std::ranges::to<std::vector>();
struct beam {
usize row;
usize col;
};
std::vector<beam> beams{};
for (usize i = 0; i < mat.size(); ++i) {
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j] == "S") {
beams.push_back({i, j});
break;
}
auto const size = beams.size();
for (usize k = 0; k < size; ++k) {
if (beams[k].row == i - 1 && beams[k].col == j) {
if (mat[i][j] == ".") {
mat[i][j] = "|";
beams[k] = {i, j};
} else if (mat[i][j] == "^") {
beams[k] = {i, j - 1};
beams.push_back({i, j + 1});
mat[i][j - 1] = "|";
mat[i][j + 1] = "|";
}
}
}
}
}
f64 sum = 0.0;
for (usize i = 0; i < mat.size(); ++i) {
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j] == "^") {
if (mat[i - 1][j] == "|") sum += 1;
}
}
}
fmt::print("res: {}\n", sum);
// for (auto const& row : mat) {
// for (auto const& col : row) {
// fmt::print("{}", col);
// }
// fmt::print("\n");
// }
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

112
2025/day09.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include <span>
#include <algorithm>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include <tuple>
#include "fmt/std.h"
#include "aoc/types.hpp"
#include "aoc/utils.hpp"
using namespace std::string_view_literals;
using namespace aoc::types;
// starts at 50
[[maybe_unused]]constexpr auto raw_str = R"(
162,817,812
57,618,57
906,360,560
592,479,940
352,342,300
466,668,158
542,29,236
431,825,988
739,650,466
52,470,668
216,146,977
819,987,18
117,168,530
805,96,715
346,949,466
970,615,88
941,993,340
862,61,35
984,92,344
425,690,689
)";
static auto entry([[maybe_unused]]std::span<char const*> const& args) -> void {
// std::string str{raw_str};
auto str = aoc::read_text("./input.txt").value_or("");
str = aoc::trim(str);
auto mat = str | std::views::split("\n"sv) | std::views::transform([](auto line) {
return line | std::views::split(""sv)
| std::views::transform([](auto tok) {
return std::string{std::begin(tok), std::end(tok)};
})
| std::ranges::to<std::vector>();
}) | std::ranges::to<std::vector>();
struct beam {
usize row;
usize col;
};
std::vector<beam> beams{};
for (usize i = 0; i < mat.size(); ++i) {
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j] == "S") {
beams.push_back({i, j});
break;
}
auto const size = beams.size();
for (usize k = 0; k < size; ++k) {
if (beams[k].row == i - 1 && beams[k].col == j) {
if (mat[i][j] == ".") {
mat[i][j] = "|";
beams[k] = {i, j};
} else if (mat[i][j] == "^") {
beams[k] = {i, j - 1};
beams.push_back({i, j + 1});
mat[i][j - 1] = "|";
mat[i][j + 1] = "|";
}
}
}
}
}
f64 sum = 0.0;
for (usize i = 0; i < mat.size(); ++i) {
for (usize j = 0; j < mat[i].size(); ++j) {
if (mat[i][j] == "^") {
if (mat[i - 1][j] == "|") sum += 1;
}
}
}
fmt::print("res: {}\n", sum);
// for (auto const& row : mat) {
// for (auto const& col : row) {
// fmt::print("{}", col);
// }
// fmt::print("\n");
// }
}
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
try {
entry({argv, std::next(argv, argc)});
} catch (std::exception const& e) {
fmt::print(stderr, "{}\n", e.what());
return 1;
}
return 0;
}

View File

@@ -3,126 +3,17 @@ project(aoc VERSION 0.0.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Group CMake targets inside a folder
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Generate compile_commands.json for language servers
include(FetchContent)
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.1.0
)
list(APPEND FETCH_CONTENTS fmt)
FetchContent_Declare(
utf8cpp
GIT_REPOSITORY https://github.com/nemtrif/utfcpp.git
GIT_TAG v4.0.5
)
list(APPEND FETCH_CONTENTS utf8cpp)
FetchContent_Declare(
stb
GIT_REPOSITORY https://github.com/mononerv/stb.git
GIT_TAG 698c6fb9889c71494b49c9187d249af5fc87b211
)
list(APPEND FETCH_CONTENTS stb)
# Turn off BUILD_TESTING globally to prevent CTest from being included in CTRE
set(BUILD_TESTING OFF CACHE BOOL "Disable testing globally" FORCE)
# Set the CTRE_BUILD_TESTS option before including the CTRE library
set(CTRE_BUILD_TESTS OFF CACHE BOOL "Build ctre Tests" FORCE)
FetchContent_Declare(
ctre
GIT_REPOSITORY https://github.com/hanickadot/compile-time-regular-expressions.git
GIT_TAG v3.9.0
)
list(APPEND FETCH_CONTENTS ctre)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/platform.cmake")
FetchContent_MakeAvailable(${FETCH_CONTENTS})
find_package(Threads REQUIRED)
# Group dependencies in Visual Studio and Xcode
if (CMAKE_GENERATOR MATCHES "Visual Studio" OR CMAKE_GENERATOR MATCHES "Xcode")
set_target_properties(fmt PROPERTIES FOLDER deps)
set_target_properties(stb PROPERTIES FOLDER deps)
endif()
set(BASE_DEFINITIONS "ASIO_STANDALONE")
if (APPLE)
message("Platform Apple")
list(APPEND BASE_DEFINITIONS
"AOC_PLATFORM=Apple"
)
set(IS_UNIX true)
elseif (UNIX AND NOT APPLE AND NOT EMSCRIPTEN) # Linux, BSD, Solaris, Minix
message("Platform Unix")
list(APPEND BASE_DEFINITIONS
"AOC_PLATFORM=Linux"
)
set(IS_UNIX true)
elseif (WIN32)
message("Platform Windows")
list(APPEND BASE_DEFINITIONS
"AOC_PLATFORM=Windows"
)
else()
message(FATAL_ERROR "Unkown platform!")
endif()
# Compiler specific options
if (NOT MSVC)
set(BASE_OPTIONS
"-Wall"
"-Wextra"
"-Wconversion"
"-Wpedantic"
"-Wshadow"
"-Werror"
# fmt warnings
"-Wno-unknown-attributes"
)
else()
set(BASE_OPTIONS
"/W4"
"/WX"
"/utf-8"
"/Zc:__cplusplus"
#"/fsanitize=address" # Doesn't work without Visual Studio
)
endif()
set(HEADERS
aoc/aoc.hpp
)
set(SOURCES "")
add_library(aoclib OBJECT ${HEADERS} ${SOURCES})
target_include_directories(aoclib
PUBLIC
${PROJECT_SOURCE_DIR}
PRIVATE
${PROJECT_SOURCE_DIR}/aoc
)
target_compile_features(aoclib PRIVATE cxx_std_23)
target_compile_options(aoclib PRIVATE ${BASE_OPTIONS})
target_compile_definitions(aoclib
PRIVATE
${BASE_DEFINITIONS}
)
target_link_libraries(aoclib
PUBLIC
fmt
utf8cpp
ctre
stb::stb
Threads::Threads
)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${HEADERS} ${SOURCES})
set(HEADERS "")
set(SOURCES aoc.cpp)
add_executable(aoc ${HEADERS} ${SOURCES})
target_include_directories(aoc PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_features(aoc PRIVATE cxx_std_23)
target_compile_options(aoc PRIVATE ${BASE_OPTIONS})
target_compile_definitions(aoc PRIVATE ${BASE_DEFINITIONS})
target_link_libraries(aoc
PRIVATE
aoclib
)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${HEADERS} ${SOURCES})
add_subdirectory("2025")
# set(HEADERS "")
# set(SOURCES "aoc.cpp")
# add_executable(aoc ${HEADERS} ${SOURCES})
# target_include_directories(aoc PUBLIC ${PROJECT_SOURCE_DIR})
# target_compile_features(aoc PRIVATE cxx_std_23)
# target_link_libraries(aoc PRIVATE ${PLATFORM_LINK_LIBRARIES})
# target_compile_definitions(aoc PRIVATE ${PLATFORM_DEFINITIONS})
# target_compile_options(aoc PRIVATE ${BASE_OPTIONS})
# source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${HEADERS} ${SOURCES})

View File

@@ -14,12 +14,6 @@ This project has support for different languages.
There are different ways to setup this project, using `ninja` or Visual Studio.
To use `miniaudio` to play audio on host machine use the flag `-DUSE_MINIAUDIO=ON`.
```sh
cmake -S . -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Debug
```
Use `ninja` to build.

72
aoc.cpp
View File

@@ -1,72 +0,0 @@
#include <fstream>
#include <vector>
#include <algorithm>
#include <ranges>
#include <numeric>
#include <cmath>
#include <utility>
#include "fmt/format.h"
#include "aoc/24/01.hpp"
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
constexpr auto filename = "./dat/24/re/01.txt";
std::ifstream strm{filename, std::ios::in};
if (!strm.is_open()) {
fmt::print("Error opening file: {}\n", filename);
return 1;
}
std::vector<std::uint32_t> a{};
std::vector<std::uint32_t> b{};
std::string str{};
while (strm) {
auto const c = char(strm.peek());
if (std::isdigit(c)) {
str += char(strm.get());
continue;
}
if (c == ' ') {
if (!str.empty()) {
a.emplace_back(std::stoi(str));
str.clear();
}
}
if (c == '\n') {
if (!str.empty()) {
b.emplace_back(std::stoi(str));
str.clear();
}
}
[[discard]]strm.get();
}
fmt::print("a: {}, b: {}\n", a.size(), b.size());
std::sort(std::begin(a), std::end(a));
std::sort(std::begin(b), std::end(b));
auto diff_view = std::views::zip(a, b) | std::views::transform([](auto const& p) {
auto const [x, y] = p;
return x > y ? x - y : y - x;
});
auto const sum = std::accumulate(std::begin(diff_view), std::end(diff_view), 0);
fmt::print("Part A: {}\n", std::abs(sum));
auto values = a | std::views::transform([&b](auto v) {
return std::pair{v, b | std::views::filter([v](auto c) {
return v == c; // Filter elements in `b` equal to `v`
}) | std::ranges::to<std::vector>()};
}) | std::ranges::to<std::vector>();
auto const meow = std::accumulate(std::begin(values), std::end(values), 0, [](auto const acc, auto const& pair) {
return acc + std::int32_t(pair.first * pair.second.size());
});
fmt::print("Part B: {}\n", meow);
return 0;
}

View File

View File

@@ -1,7 +0,0 @@
#ifndef AOC_AOC_HPP
#define AOC_AOC_HPP
namespace aoc {
}
#endif // !AOC_AOC_HPP

41
aoc/types.hpp Normal file
View File

@@ -0,0 +1,41 @@
#ifndef AOC_TYPES_HPP
#define AOC_TYPES_HPP
#include <type_traits>
#include <cstddef>
#include <limits>
#include <numbers>
#include <memory>
#include <system_error>
#include <expected>
#include <fstream>
#include <ranges>
#include <vector>
namespace aoc {
namespace types {
using f32 = float;
using f64 = double;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using usize = std::size_t;
using isize = std::ptrdiff_t;
using i8 = std::int8_t;
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using c8 = char;
using c16 = char16_t;
using c32 = char32_t;
}
using namespace aoc::types;
}
#endif // !AOC_TYPES_HPP

107
aoc/utils.hpp Normal file
View File

@@ -0,0 +1,107 @@
#ifndef AOC_UTILS_HPP
#define AOC_UTILS_HPP
#include <type_traits>
#include <cstddef>
#include <limits>
#include <numbers>
#include <memory>
#include <system_error>
#include <expected>
#include <fstream>
#include <ranges>
#include <vector>
#include <string>
#include "aoc/types.hpp"
namespace aoc {
template <typename T>
concept Integral = std::is_integral<T>::value;
// Aliases
namespace nums = std::numbers;
template <typename T>
using lim = std::numeric_limits<T>;
inline constexpr auto pi = std::numbers::pi;
template <typename T>
inline constexpr auto pi_v = std::numbers::pi_v<T>;
struct error {
std::string msg;
std::error_code err;
};
inline auto make_error(std::string const& str, std::errc ec) -> std::unexpected<error> {
return std::unexpected(error{str, std::make_error_code(ec)});
}
inline auto read_text(std::string const& path) -> std::expected<std::string, aoc::error> {
std::fstream strm(path, std::ios::in | std::ios::binary);
if (!strm.is_open())
return aoc::make_error(path, std::errc::no_such_file_or_directory);
return std::string{
std::istreambuf_iterator<c8>(strm),
std::istreambuf_iterator<c8>()
};
}
// ranges and view aliases
template <typename T>
using vec = std::vector<T>;
inline constexpr auto split = std::views::split;
[[maybe_unused]]constexpr auto map_to_str = std::views::transform([](auto const& str) {
return std::string(std::begin(str), std::end(str));
});
[[maybe_unused]]constexpr auto map_to_sv = std::views::transform([](auto const& str) {
return std::string_view(std::begin(str), std::end(str));
});
[[maybe_unused]]constexpr auto filter_non_empty = std::views::filter([](auto const& str) {
return !str.empty();
});
template <class F>
struct pipe {
F f;
};
template <class F>
pipe(F) -> pipe<F>;
template <class F>
auto operator|(std::string s, pipe<F> p) -> decltype(auto) {
return p.f(std::move(s));
}
inline auto ltrim(std::string s) -> std::string {
s.erase(
std::begin(s),
std::find_if(s.begin(), s.end(), [](char ch) {
return !std::isspace(static_cast<char>(ch));
}));
return s;
}
inline auto rtrim(std::string s) -> std::string {
s.erase(
std::find_if(s.rbegin(), s.rend(), [](char ch) {
return !std::isspace(static_cast<char>(ch));
}).base(),
s.end());
return s;
}
inline auto trim(std::string s) -> std::string {
return ltrim(rtrim(std::move(s)));
}
}
#endif // !AOC_UTILS_HPP

74
cmake/Findctre.cmake Normal file
View File

@@ -0,0 +1,74 @@
if (DEFINED _FINDCTRE_INCLUDED)
unset(ctre_FOUND CACHE)
unset(ctre_DIR CACHE)
unset(ctre_INCLUDE_DIR CACHE)
unset(ctre_LIBRARIES CACHE)
unset(ctre_VERSION CACHE)
return()
endif()
set(_FINDCTRE_INCLUDED TRUE)
find_package(ctre QUIET)
if (NOT ctre_FOUND)
message(STATUS "ctre not found. Fetching via FetchContent...")
include(FetchContent)
find_program(GIT_EXECUTABLE git)
if (GIT_EXECUTABLE)
set(CTRE_FETCH_METHOD "GIT")
else()
set(CTRE_FETCH_METHOD "ZIP")
endif()
if (CTRE_FETCH_METHOD STREQUAL "GIT")
FetchContent_Declare(
ctre
GIT_REPOSITORY https://github.com/hanickadot/compile-time-regular-expressions.git
GIT_TAG v3.10.0
)
else()
FetchContent_Declare(
ctre
URL https://github.com/hanickadot/compile-time-regular-expressions/archive/refs/tags/v3.10.0.zip
)
endif()
# Turn off BUILD_TESTING globally to prevent CTest from being included in CTRE
set(BUILD_TESTING OFF CACHE BOOL "Disable testing globally" FORCE)
# Set the CTRE_BUILD_TESTS option before including the CTRE library
set(CTRE_BUILD_TESTS OFF CACHE BOOL "Build ctre Tests" FORCE)
FetchContent_MakeAvailable(ctre)
else()
message(STATUS "ctre found.")
# Ensure we have a usable target
if (NOT TARGET ctre::ctre)
if (TARGET ctre)
add_library(ctre::ctre ALIAS ctre)
else()
message(FATAL_ERROR "ctre was found, but no CMake target 'ctre' or 'ctre::ctre' exists.")
endif()
endif()
# Populate the standard variables
set(ctre_FOUND TRUE)
set(ctre_LIBRARIES ctre::ctre)
get_target_property(_ctre_inc ctre::ctre INTERFACE_INCLUDE_DIRECTORIES)
set(ctre_INCLUDE_DIR "${_ctre_inc}")
endif()
if (NOT TARGET ctre::ctre)
if (TARGET ctre)
add_library(ctre::ctre ALIAS ctre)
else()
message(FATAL_ERROR "Could not find or fetch ctre; no target ctre or ctre::ctre available")
endif()
endif()
set(ctre_FOUND TRUE)
set(ctre_LIBRARIES ctre::ctre)
set(ctre_VERSION "${ctre_VERSION}") # this comes from the ctre project
get_target_property(_ctre_inc ctre::ctre INTERFACE_INCLUDE_DIRECTORIES)
set(ctre_INCLUDE_DIR "${_ctre_inc}")

70
cmake/Findfmt.cmake Normal file
View File

@@ -0,0 +1,70 @@
if (DEFINED _FINDFMT_INCLUDED)
unset(fmt_FOUND CACHE)
unset(fmt_DIR CACHE)
unset(fmt_INCLUDE_DIR CACHE)
unset(fmt_LIBRARIES CACHE)
unset(fmt_VERSION CACHE)
return()
endif()
set(_FINDFMT_INCLUDED TRUE)
find_package(fmt QUIET)
if (NOT fmt_FOUND)
message(STATUS "fmt not found. Fetching via FetchContent...")
include(FetchContent)
find_program(GIT_EXECUTABLE git)
if (GIT_EXECUTABLE)
set(FMT_FETCH_METHOD "GIT")
else()
set(FMT_FETCH_METHOD "ZIP")
endif()
if (FMT_FETCH_METHOD STREQUAL "GIT")
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 12.0.0
)
else()
FetchContent_Declare(
fmt
URL https://github.com/fmtlib/fmt/releases/download/12.0.0/fmt-12.0.0.zip
)
endif()
FetchContent_MakeAvailable(fmt)
else()
message(STATUS "fmt found.")
# Ensure we have a usable target
if (NOT TARGET fmt::fmt)
if (TARGET fmt)
add_library(fmt::fmt ALIAS fmt)
else()
message(FATAL_ERROR "fmt was found, but no CMake target 'fmt' or 'fmt::fmt' exists.")
endif()
endif()
# Populate the standard variables
set(fmt_FOUND TRUE)
set(fmt_LIBRARIES fmt::fmt)
get_target_property(_fmt_inc fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
set(fmt_INCLUDE_DIR "${_fmt_inc}")
endif()
if (NOT TARGET fmt::fmt)
if (TARGET fmt)
add_library(fmt::fmt ALIAS fmt)
else()
message(FATAL_ERROR "Could not find or fetch fmt; no target fmt or fmt::fmt available")
endif()
endif()
set(fmt_FOUND TRUE)
set(fmt_LIBRARIES fmt::fmt)
set(fmt_VERSION "${fmt_VERSION}") # this comes from the fmt project
get_target_property(_fmt_inc fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
set(fmt_INCLUDE_DIR "${_fmt_inc}")

70
cmake/Findutf8cpp.cmake Normal file
View File

@@ -0,0 +1,70 @@
if (DEFINED _FINDUTF8CPP_INCLUDED)
unset(utf8cpp_FOUND CACHE)
unset(utf8cpp_DIR CACHE)
unset(utf8cpp_INCLUDE_DIR CACHE)
unset(utf8cpp_LIBRARIES CACHE)
unset(utf8cpp_VERSION CACHE)
return()
endif()
set(_FINDUTF8CPP_INCLUDED TRUE)
find_package(utf8cpp QUIET)
if (NOT utf8cpp_FOUND)
message(STATUS "utf8cpp not found. Fetching via FetchContent...")
include(FetchContent)
find_program(GIT_EXECUTABLE git)
if (GIT_EXECUTABLE)
set(UTF8CPP_FETCH_METHOD "GIT")
else()
set(UTF8CPP_FETCH_METHOD "ZIP")
endif()
if (UTF8CPP_FETCH_METHOD STREQUAL "GIT")
FetchContent_Declare(
utf8cpp
GIT_REPOSITORY https://github.com/nemtrif/utfcpp.git
GIT_TAG v4.0.6
)
else()
FetchContent_Declare(
utf8cpp
URL https://github.com/nemtrif/utfcpp/archive/refs/tags/v4.0.6.zip
)
endif()
FetchContent_MakeAvailable(utf8cpp)
else()
message(STATUS "utf8cpp found.")
# Ensure we have a usable target
if (NOT TARGET utf8cpp::utf8cpp)
if (TARGET utf8cpp)
add_library(utf8cpp::utf8cpp ALIAS utf8cpp)
else()
message(FATAL_ERROR "utf8cpp was found, but no CMake target 'utf8cpp' or 'utf8cpp::utf8cpp' exists.")
endif()
endif()
# Populate the standard variables
set(utf8cpp_FOUND TRUE)
set(utf8cpp_LIBRARIES utf8cpp::utf8cpp)
get_target_property(_utf8cpp_inc utf8cpp::utf8cpp INTERFACE_INCLUDE_DIRECTORIES)
set(utf8cpp_INCLUDE_DIR "${_utf8cpp_inc}")
endif()
if (NOT TARGET utf8cpp::utf8cpp)
if (TARGET utf8cpp)
add_library(utf8cpp::utf8cpp ALIAS utf8cpp)
else()
message(FATAL_ERROR "Could not find or fetch utf8cpp; no target utf8cpp or utf8cpp::utf8cpp available")
endif()
endif()
set(utf8cpp_FOUND TRUE)
set(utf8cpp_LIBRARIES utf8cpp::utf8cpp)
set(utf8cpp_VERSION "${utf8cpp_VERSION}") # this comes from the utf8cpp project
get_target_property(_utf8cpp_inc utf8cpp::utf8cpp INTERFACE_INCLUDE_DIRECTORIES)
set(utf8cpp_INCLUDE_DIR "${_utf8cpp_inc}")

98
cmake/platform.cmake Normal file
View File

@@ -0,0 +1,98 @@
# cmake/platform.cmake
# Platform detection + compiler options
if(DEFINED PLATFORM_CONFIG_INCLUDED)
return()
endif()
set(PLATFORM_CONFIG_INCLUDED TRUE)
# -------------------------------------------------------
# Platform detection
# -------------------------------------------------------
if(APPLE)
set(PLATFORM "macOS")
message(STATUS "Platform: ${PLATFORM}")
set(PLATFORM_LINK_LIBRARIES
"-framework Cocoa"
"-framework IOKit"
"-framework CoreVideo"
"-framework OpenGL"
)
elseif(UNIX AND NOT APPLE AND NOT EMSCRIPTEN) # Linux, BSD, etc.
set(PLATFORM "Linux")
message(STATUS "Platform: ${PLATFORM}")
set(PLATFORM_LINK_LIBRARIES
dl
m
GL
X11
)
elseif(WIN32)
set(PLATFORM "Windows")
message(STATUS "Platform: ${PLATFORM}")
set(PLATFORM_LINK_LIBRARIES
OpenGL32.lib
)
set(PLATFORM_DEFINITIONS
${PLATFORM_DEFINITIONS}
"_WIN32_WINNT=0x0A00"
)
elseif(EMSCRIPTEN)
set(PLATFORM "Emscripten")
message(STATUS "Platform: ${PLATFORM}")
# Emscripten specific flags (not the warnings; those are below)
add_compile_options(
-pthread
-fexceptions
-sUSE_PTHREADS=1
)
add_link_options(
-pthread
-fexceptions
-sUSE_PTHREADS=1
)
else()
message(FATAL_ERROR "Platform: Unknown!")
endif()
# -------------------------------------------------------
# Compiler specific options (BASE_OPTIONS)
# -------------------------------------------------------
if(NOT MSVC)
set(BASE_OPTIONS
-Wall
-Wextra
# -Werror
# fmt warnings
-Wno-deprecated-literal-operator
)
if(EMSCRIPTEN)
list(APPEND BASE_OPTIONS
# asio
-Wno-sign-conversion
-Wno-shadow
-Wno-shorten-64-to-32
-Wno-implicit-int-conversion
-Wno-unused-private-field
-Wno-deprecated-declarations
)
endif()
else()
set(BASE_OPTIONS
/W4
# /WX # warnings as errors (MSVC equivalent of -Werror)
/utf-8
/Zc:__cplusplus
#/fsanitize=address # Doesn't work without Visual Studio
)
endif()

View File

@@ -1,6 +0,0 @@
3 4
4 3
2 5
1 3
3 9
3 3

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +0,0 @@
project(
'aoc',
['cpp', 'c++']
version: '0.0.0',
default_options: [
'c_std=c2x',
'cpp_std=c++23'
]
)
executable(
'aoc',
[
'aoc.cpp'
],
include_directories: [
include_directories('.')
]
)