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