aoc24: day03 tokenizer

This commit is contained in:
2024-12-03 16:43:38 +01:00
parent 616f6bd610
commit c685dcddfb
13 changed files with 328 additions and 155 deletions

15
sol/24/01/CMakeLists.txt Normal file
View File

@@ -0,0 +1,15 @@
set(HEADERS "")
set(SOURCES entry.cpp)
add_executable(sol2401 ${HEADERS} ${SOURCES})
target_include_directories(sol2401 PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_features(sol2401 PRIVATE cxx_std_23)
target_compile_options(sol2401 PRIVATE ${BASE_OPTIONS})
target_compile_definitions(sol2401 PRIVATE ${BASE_DEFINITIONS})
target_link_libraries(sol2401
PRIVATE
aoc
)
set_target_properties(sol2401 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${HEADERS} ${SOURCES})

61
sol/24/01/entry.cpp Normal file
View File

@@ -0,0 +1,61 @@
#include "aoc/aoc.hpp"
#include "fmt/format.h"
// auto aoc::entry([[maybe_unused]]std::vector<std::string_view> const& args) -> void {
// 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);
// }

15
sol/24/02/CMakeLists.txt Normal file
View File

@@ -0,0 +1,15 @@
set(HEADERS "")
set(SOURCES entry.cpp)
add_executable(sol2402 ${HEADERS} ${SOURCES})
target_include_directories(sol2402 PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_features(sol2402 PRIVATE cxx_std_23)
target_compile_options(sol2402 PRIVATE ${BASE_OPTIONS})
target_compile_definitions(sol2402 PRIVATE ${BASE_DEFINITIONS})
target_link_libraries(sol2402
PRIVATE
aoc
)
set_target_properties(sol2402 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${HEADERS} ${SOURCES})

7
sol/24/02/entry.cpp Normal file
View File

@@ -0,0 +1,7 @@
#include "aoc/aoc.hpp"
#include "fmt/format.h"
auto aoc::entry([[maybe_unused]]std::vector<std::string_view> const& args) -> void {
fmt::print("Hello, World!\n");
}

15
sol/24/03/CMakeLists.txt Normal file
View File

@@ -0,0 +1,15 @@
set(HEADERS "")
set(SOURCES entry.cpp)
add_executable(sol2403 ${HEADERS} ${SOURCES})
target_include_directories(sol2403 PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_features(sol2403 PRIVATE cxx_std_23)
target_compile_options(sol2403 PRIVATE ${BASE_OPTIONS})
target_compile_definitions(sol2403 PRIVATE ${BASE_DEFINITIONS})
target_link_libraries(sol2403
PRIVATE
aoc
)
set_target_properties(sol2403 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${HEADERS} ${SOURCES})

186
sol/24/03/entry.cpp Normal file
View File

@@ -0,0 +1,186 @@
#include <fstream>
#include <expected>
#include <string>
#include "aoc/aoc.hpp"
#include "fmt/format.h"
#include "ctre.hpp"
#define ENUMERATOR_AOC_TOKENS \
ENUMERATOR_AOC_TOKEN(mul , operator_ ) \
ENUMERATOR_AOC_TOKEN(invalid , invalid ) \
ENUMERATOR_AOC_TOKEN(numeric_literal, number ) \
ENUMERATOR_AOC_TOKEN(newline , punctuation) \
ENUMERATOR_AOC_TOKEN(paren_open , punctuation) \
ENUMERATOR_AOC_TOKEN(paren_close , punctuation) \
ENUMERATOR_AOC_TOKEN(comma , punctuation) \
ENUMERATOR_AOC_TOKEN(identifier , identifier )
enum class token_type : std::uint32_t {
#define ENUMERATOR_AOC_TOKEN(type, category) type,
ENUMERATOR_AOC_TOKENS
#undef ENUMERATOR_AOC_TOKEN
_count
};
enum class token_category : std::uint32_t {
operator_,
invalid,
number,
punctuation,
identifier,
_count
};
auto token_type_str(token_type type) -> char const* {
switch (type) {
using enum token_type;
#define ENUMERATOR_AOC_TOKEN(type, category) case type: return #type;
ENUMERATOR_AOC_TOKENS
#undef ENUMERATOR_AOC_TOKEN
default: return "invalid";
}
}
auto token_type_category(token_type type) -> token_category {
switch (type) {
using enum token_category;
#define ENUMERATOR_AOC_TOKEN(type, category) case token_type::type: return category;
ENUMERATOR_AOC_TOKENS
#undef ENUMERATOR_AOC_TOKEN
default: return token_category::invalid;
}
}
class token {
public:
token(std::string const& str, token_type type, token_category category, std::size_t row, std::size_t col)
: m_type(type)
, m_category(category)
, m_value(str)
, m_row(row)
, m_column(col) { }
auto type() const -> token_type { return m_type; }
auto category() const -> token_category { return m_category; }
auto value() const -> std::string const& { return m_value; }
auto row() const -> std::size_t { return m_row; }
auto col() const -> std::size_t { return m_column; }
auto str() const -> std::string {
using namespace std::string_literals;
std::string str{"token {"};
str += " type: "s + token_type_str(m_type) + ","s;
str += " value: \""s + m_value + "\","s;
str += " row: "s + std::to_string(m_row) + ","s;
str += " col: "s + std::to_string(m_column);
str += " }";
return str;
}
public:
inline static auto is_identifier(std::string_view const& str) -> bool {
return ctre::match<"^[a-z]+$">(str);
}
private:
token_type m_type;
token_category m_category;
std::string m_value;
std::size_t m_row;
std::size_t m_column;
};
enum class lexer_error {
eof,
unknown
};
class lexer {
public:
lexer(std::filesystem::path const& source)
: m_strm(source, std::ios::in | std::ios::binary)
, m_line(1), m_col(1) {
}
auto tokenize() -> std::vector<token> {
std::vector<token> tokens{};
auto tk = next_token();
while (tk) {
tokens.emplace_back(std::move(tk.value()));
tk = next_token();
}
return tokens;
}
private:
auto next_token() -> std::optional<token> {
if (!has_next()) return {};
if (peek() == '\n') {
peek_consume();
m_line = m_line + 1;
m_col = 0;
}
std::string str{};
if (peek() == 'm') {
auto const col = m_col;
auto const is_valid_identifier_char = [](auto const c) {
return c >= 'a' && c <= 'z';
};
while (is_valid_identifier_char(peek())) str += peek_consume();
auto const& type = token::is_identifier(str) ? token_type::identifier : token_type::invalid;
return token(str, type, token_type_category(type), m_line, col);
}
if (peek() == '(') {
auto const col = m_col;
str += peek_consume();
return token(str, token_type::paren_open, token_type_category(token_type::paren_open), m_line, col);
}
if (peek() == ')') {
auto const col = m_col;
str += peek_consume();
return token(str, token_type::paren_close, token_type_category(token_type::paren_close), m_line, col);
}
if (peek() == ',') {
auto const col = m_col;
str += peek_consume();
return token(str, token_type::comma, token_type_category(token_type::comma), m_line, col);
}
auto const col = m_col;
str += peek_consume();
return token(str, token_type::invalid, token_type_category(token_type::invalid), m_line, col);
}
auto peek() -> char {
return static_cast<char>(m_strm.peek());
}
auto peek_consume() -> char {
++m_col;
return static_cast<char>(m_strm.get());
}
auto has_next() const -> bool {
return !m_strm.eof();
}
private:
std::fstream m_strm;
std::size_t m_line;
std::size_t m_col;
};
auto aoc::entry([[maybe_unused]]std::vector<std::string_view> const& args) -> void {
lexer lexer{"./dat/24/ex/03.txt"};
auto const tokens = lexer.tokenize();
for (auto const& tk : tokens) {
fmt::print("{}\n", tk.str());
}
}

3
sol/24/CMakeLists.txt Normal file
View File

@@ -0,0 +1,3 @@
# add_subdirectory(01)
# add_subdirectory(02)
add_subdirectory(03)