Compare commits
31 Commits
day02
...
ed04586b1d
| Author | SHA1 | Date | |
|---|---|---|---|
| ed04586b1d | |||
| 11ed18a199 | |||
| 65f6175bc9 | |||
| 60e78353d7 | |||
| b90bcb0c9d | |||
| 7fb1f4f778 | |||
| abecf6cfb7 | |||
| 432a5b1f7c | |||
| 14ec3ca2da | |||
| d106e7541d | |||
| 49d82b8f90 | |||
| c238e9b4fb | |||
| da8a4cc5de | |||
| 5810fe22e9 | |||
| 5c7da45fe1 | |||
| 9c840a7c8f | |||
| 1108b8c65b | |||
| 7ae660566e | |||
| 521b3dc806 | |||
| c175b4ebc4 | |||
| ec9028c5f5 | |||
| aaff50eae9 | |||
| 57d9bdf0f3 | |||
| a35123500e | |||
| 5a02b90f85 | |||
| a1d5d359f2 | |||
| 5c692fe727 | |||
| 8df8cbb0e4 | |||
| 1c6bbc6cef | |||
| 9e68114169 | |||
| c685dcddfb |
38
2025/CMakeLists.txt
Normal file
38
2025/CMakeLists.txt
Normal 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
127
2025/day01.cpp
Normal 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
90
2025/day02.cpp
Normal 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
73
2025/day03.cpp
Normal 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
83
2025/day04.cpp
Normal 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;
|
||||
}
|
||||
90
2025/day05.cpp
Normal file
90
2025/day05.cpp
Normal 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"(
|
||||
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);
|
||||
|
||||
fmt::print("INPUT\n");
|
||||
fmt::print("⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼⎽⎼⎻⎺⎻⎼\n");
|
||||
fmt::print("{}\n", str);
|
||||
fmt::print("{}\n", std::string(80, '-'));
|
||||
|
||||
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>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
84
2025/day06.cpp
Normal file
84
2025/day06.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#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("\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 std::string{std::begin(tok), std::end(tok)};
|
||||
})
|
||||
| std::ranges::to<std::vector>();
|
||||
}) | std::ranges::to<std::vector>();
|
||||
|
||||
std::vector<std::vector<f64>> 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(std::stod(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 *= nums[i][j];
|
||||
else if (op == "+") row_sum += nums[i][j];
|
||||
}
|
||||
// fmt::print("sum: {}\n", row_sum);
|
||||
sum += row_sum;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
108
2025/day07.cpp
Normal file
108
2025/day07.cpp
Normal 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;
|
||||
}
|
||||
133
CMakeLists.txt
133
CMakeLists.txt
@@ -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})
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
142
aoc.cpp
142
aoc.cpp
@@ -1,142 +0,0 @@
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
using levels_t = std::vector<std::int32_t>;
|
||||
using reports_t = std::vector<levels_t>;
|
||||
|
||||
auto main([[maybe_unused]]int argc, [[maybe_unused]]char const* argv[]) -> int {
|
||||
// constexpr auto filename = "./dat/24/ex/02.txt";
|
||||
constexpr auto filename = "./tmp.txt";
|
||||
std::ifstream strm{filename, std::ios::in | std::ios::binary};
|
||||
if (!strm.is_open()) {
|
||||
fmt::print("Error opening file: {}\n", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
reports_t reports{};
|
||||
|
||||
levels_t tmp{};
|
||||
std::string str{};
|
||||
while (strm) {
|
||||
auto const c = char(strm.peek());
|
||||
if (std::isdigit(c)) {
|
||||
str += char(strm.get());
|
||||
continue;
|
||||
}
|
||||
if (c == ' ' && !str.empty()) {
|
||||
tmp.emplace_back(std::stoi(str));
|
||||
str.clear();
|
||||
}
|
||||
if (c == '\n' && !str.empty()) {
|
||||
tmp.emplace_back(std::stoi(str));
|
||||
reports.emplace_back(std::move(tmp));
|
||||
str.clear();
|
||||
}
|
||||
strm.get();
|
||||
}
|
||||
|
||||
auto diff = reports | std::views::transform([](auto const& levels) {
|
||||
return levels | std::views::adjacent_transform<2>([](auto const& a, auto const& b) {
|
||||
return b - a;
|
||||
});
|
||||
});
|
||||
|
||||
// condition: all increasing or all decreasing.
|
||||
auto incdec = diff | std::views::filter([](auto const& levels) {
|
||||
auto const n = std::ranges::all_of(levels, [](auto v) { return v < 0; });
|
||||
auto const p = std::ranges::all_of(levels, [](auto v) { return v > 0; });
|
||||
return n || p;
|
||||
});
|
||||
|
||||
// condition: Any two adjacent levels differ by at least one and at most three.
|
||||
auto adjdiff = incdec | std::views::filter([](auto const& levels){
|
||||
return std::ranges::all_of(levels, [](auto v) {
|
||||
return std::abs(v) <= 3;
|
||||
});
|
||||
});
|
||||
|
||||
auto const safe_reports = std::ranges::distance(adjdiff);
|
||||
|
||||
fmt::print("Part A: {}\n", safe_reports);
|
||||
|
||||
auto lefts = std::views::zip(diff, reports) | std::views::filter([](auto const& pair) {
|
||||
auto const& [d, l] = pair;
|
||||
auto const n = std::ranges::all_of(d, [](auto v) { return v < 0; });
|
||||
auto const p = std::ranges::all_of(d, [](auto v) { return v > 0; });
|
||||
return !(n || p);
|
||||
}) | std::views::transform([](auto const& pair) {
|
||||
auto const& [d, l] = pair;
|
||||
return l;
|
||||
});
|
||||
|
||||
auto masks = diff | std::views::filter([](auto const& vec) {
|
||||
auto const n = std::ranges::all_of(vec, [](auto v) { return v < 0; });
|
||||
auto const p = std::ranges::all_of(vec, [](auto v) { return v > 0; });
|
||||
return !(n || p);
|
||||
}) | std::views::transform([](auto const& vec) {
|
||||
auto const p = std::count_if(std::begin(vec), std::end(vec), [](auto const& v) { return v >= 0; });
|
||||
auto const n = std::count_if(std::begin(vec), std::end(vec), [](auto const& v) { return v < 0; });
|
||||
auto mask = vec | std::views::transform([&](auto const& v) {
|
||||
if (p > n) return v >= 0 ? 1 : 0;
|
||||
else return v < 0 ? 1 : 0;
|
||||
}) | std::ranges::to<std::vector>();
|
||||
mask.push_back(1);
|
||||
return mask;
|
||||
});
|
||||
|
||||
auto const remain_reports = std::views::zip(masks, lefts)
|
||||
| std::views::filter([](auto const& pair) {
|
||||
auto const& [mask, level] = pair;
|
||||
auto const n = std::count_if(std::begin(mask), std::end(mask), [](auto const& v) { return v == 0; });
|
||||
return n == 1;
|
||||
})
|
||||
| std::views::transform([](auto const& pair){
|
||||
auto const& [mask, level] = pair;
|
||||
|
||||
return std::views::zip(mask, level) | std::views::filter([](auto const& pair) {
|
||||
auto const& [m, v] = pair;
|
||||
return m == 1;
|
||||
}) | std::views::transform([](auto const& pair) {
|
||||
auto const& [m, v] = pair;
|
||||
return v;
|
||||
}) | std::ranges::to<std::vector>();
|
||||
})
|
||||
| std::ranges::to<std::vector>();
|
||||
|
||||
auto rem_diff = remain_reports | std::views::transform([](auto const& vec) {
|
||||
return vec | std::views::adjacent_transform<2>([](auto const& a, auto const& b) { return b - a; });
|
||||
});
|
||||
|
||||
auto safe_rems_vec = rem_diff | std::views::transform([](auto const& vec) {
|
||||
return vec | std::views::filter([](auto const& a) {
|
||||
return std::abs(a) <= 3;
|
||||
}) | std::ranges::to<std::vector>();
|
||||
}) | std::ranges::to<std::vector>();
|
||||
|
||||
auto safe_rems = safe_rems_vec | std::views::filter([](auto const& vec) {
|
||||
return vec.size() > 0;
|
||||
}) | std::views::filter([](auto const& vec) {
|
||||
auto const n = std::ranges::all_of(vec, [](auto v) { return v < 0; });
|
||||
auto const p = std::ranges::all_of(vec, [](auto v) { return v > 0; });
|
||||
return n || p;
|
||||
});
|
||||
|
||||
auto const safe_reports_rem = std::ranges::distance(safe_rems);
|
||||
|
||||
// for (auto rep : safe_rems) {
|
||||
// for (auto v : rep) {
|
||||
// fmt::print("{} ", v);
|
||||
// }
|
||||
// fmt::print("\n");
|
||||
// }
|
||||
fmt::print("Part B: {}\n", safe_reports + safe_reports_rem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef AOC_AOC_HPP
|
||||
#define AOC_AOC_HPP
|
||||
|
||||
namespace aoc {
|
||||
}
|
||||
|
||||
#endif // !AOC_AOC_HPP
|
||||
41
aoc/types.hpp
Normal file
41
aoc/types.hpp
Normal 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
107
aoc/utils.hpp
Normal 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
74
cmake/Findctre.cmake
Normal 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
70
cmake/Findfmt.cmake
Normal 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
70
cmake/Findutf8cpp.cmake
Normal 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
98
cmake/platform.cmake
Normal 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()
|
||||
@@ -1,6 +0,0 @@
|
||||
3 4
|
||||
4 3
|
||||
2 5
|
||||
1 3
|
||||
3 9
|
||||
3 3
|
||||
@@ -1,6 +0,0 @@
|
||||
7 6 4 2 1
|
||||
1 2 7 8 9
|
||||
9 7 6 2 1
|
||||
1 3 2 4 5
|
||||
8 6 4 4 1
|
||||
1 3 6 7 9
|
||||
1000
dat/24/re/01.txt
1000
dat/24/re/01.txt
File diff suppressed because it is too large
Load Diff
1000
dat/24/re/02.txt
1000
dat/24/re/02.txt
File diff suppressed because it is too large
Load Diff
19
meson.build
19
meson.build
@@ -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('.')
|
||||
]
|
||||
)
|
||||
Reference in New Issue
Block a user