update
This commit is contained in:
parent
38004618a6
commit
35d509754f
8 changed files with 303 additions and 11 deletions
13
pb_2/CMakeLists.txt
Normal file
13
pb_2/CMakeLists.txt
Normal 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
151
pb_2/problem_2.cpp
Normal 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
14
pb_2/problem_2.hpp
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue