0
0
Fork 0
This commit is contained in:
Pcornat 2024-06-05 16:30:59 +02:00
parent 38004618a6
commit 35d509754f
Signed by: Pcornat
GPG key ID: E0326CC678A00BDD
8 changed files with 303 additions and 11 deletions

13
pb_2/CMakeLists.txt Normal file
View file

@ -0,0 +1,13 @@
project(pb_2 CXX)
find_package(Boost REQUIRED)
add_library(pb_2 STATIC problem_2.cpp problem_2.hpp)
target_include_directories(pb_2 PRIVATE ${Boost_INCLUDE_DIR})
target_compile_definitions(pb_2 PUBLIC $<$<AND:$<CONFIG:Debug>,$<STREQUAL:$<CXX_COMPILER_ID>,GNU>>:_GLIBCXX_DEBUG>)
#target_compile_options(pb_2 PUBLIC ${COMPILE_FLAGS})
#target_link_options(pb_2 PUBLIC ${LINKER_OPTIONS})

151
pb_2/problem_2.cpp Normal file
View file

@ -0,0 +1,151 @@
//
// Created by postaron on 17/01/24.
//
#include "problem_2.hpp"
#include <optional>
#include <iostream>
#include <fstream>
#include <format>
#include <list>
#include <algorithm>
#include <numeric>
#include <charconv>
#include <boost/algorithm/string.hpp>
namespace pb2 {
struct Cube final {
int red{ 0 };
int green{ 0 };
int blue{ 0 };
constexpr Cube() noexcept = default;
constexpr Cube(int red, int green, int blue) noexcept: red(red), green(green), blue(blue) {}
friend std::ostream &operator<<(std::ostream &os, const Cube &cube) {
os << "red: " << cube.red << " green: " << cube.green << " blue: " << cube.blue;
return os;
}
Cube &operator+=(const Cube &rhs) noexcept {
red += rhs.red;
green += rhs.green;
blue += rhs.blue;
return *this;
}
friend Cube operator+(Cube lhs, const Cube &rhs) noexcept {
lhs += rhs;
return lhs;
}
};
std::optional<std::ifstream> read_file(const fs::path &problemFile) noexcept {
std::ifstream file(problemFile);
if (!file.is_open()) {
const auto error_state = file.rdstate();
switch (error_state) {
case std::ios::badbit:
std::cerr << "Fatal I/O error occurred.\n";
break;
case std::ios::eofbit:
std::cerr << "End of file reached.\n";
break;
case std::ios::failbit:
std::cerr << "Non-fatal I/O error occurred.\n";
break;
default:
std::cerr << "impossible to reach.\n";
break;
}
const auto path_string = problemFile.string();
const auto msg = std::format("Failed to open file {}: ", path_string);
std::perror(msg.c_str());
return std::nullopt;
}
return file;
}
Cube parse_line(const std::string &line) {
std::list<std::string_view> cubes_str;
std::list<Cube> cubes;
std::vector<std::string_view> cube_str;
cube_str.reserve(2);
std::string_view line_view = line;
line_view = line_view.substr(line.find_first_of(':') + 1);
boost::split(cubes_str, line_view.cbegin(), boost::is_any_of(","));
return std::transform_reduce(cubes_str.begin(),
cubes_str.end(),
Cube{},
std::plus<>{},
[&cube_str](std::string_view &str) -> Cube {
str = str.substr(1);
const std::string tmp(str.cbegin(), str.cend());
boost::split(cube_str, tmp, boost::is_any_of(" "));
Cube cube;
const auto &chars = cube_str.front();
switch (cube_str.back().size()) {
case 3:
// means it's red
if (const auto result = std::from_chars(chars.data(),
chars.data() + chars.size(),
cube.red);
result.ec != std::errc{}) {
std::cerr << "Error: "
<< std::quoted(std::make_error_code(result.ec).message())
<< '\n';
}
break;
case 4:
// means it's blue
if (const auto result = std::from_chars(chars.data(),
chars.data() + chars.size(),
cube.blue);
result.ec != std::errc{}) {
std::cerr << "Error: "
<< std::quoted(std::make_error_code(result.ec).message())
<< '\n';
}
break;
default:
// means it's green
if (const auto result = std::from_chars(chars.data(),
chars.data() + chars.size(),
cube.green);
result.ec != std::errc{}) {
std::cerr << "Error: "
<< std::quoted(std::make_error_code(result.ec).message())
<< '\n';
}
break;
}
cube_str.clear();
return cube;
});
}
constexpr int maxRed = 12;
constexpr int maxGreen = 13;
constexpr int maxBlue = 14;
std::size_t problem_part1(const fs::path &problemFile) noexcept {
auto file_optional = read_file(problemFile);
if (!file_optional) {
return 0;
}
std::ifstream &file = *file_optional;
int i = 1;
int output = 0;
for (std::string line; std::getline(file, line); ++i) {
std::replace(line.begin(), line.end(), ';', ',');
auto tmp = parse_line(line);
if (tmp.red <= maxRed && tmp.green <= maxGreen && tmp.blue <= maxBlue) {
output += i;
}
}
return output;
}
}

14
pb_2/problem_2.hpp Normal file
View file

@ -0,0 +1,14 @@
#ifndef ADVENTOFCODE2023_PROBLEM_2_HPP
#define ADVENTOFCODE2023_PROBLEM_2_HPP
#include <filesystem>
namespace pb2 {
namespace fs = std::filesystem;
std::size_t problem_part1(const fs::path &problemFile) noexcept;
std::size_t problem_part2(const fs::path &problemFile) noexcept;
}
#endif //ADVENTOFCODE2023_PROBLEM_2_HPP