From 56e890cec0a28c0a485212ccebfaf774235a79a2 Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Wed, 3 Jan 2024 23:35:54 +0100 Subject: prepare for more puzzles ... :) --- 2023/src/day03.cpp | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 2023/src/day03.cpp (limited to '2023/src/day03.cpp') diff --git a/2023/src/day03.cpp b/2023/src/day03.cpp new file mode 100644 index 0000000..b266f59 --- /dev/null +++ b/2023/src/day03.cpp @@ -0,0 +1,174 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +vector +read_file(string_view filename) +{ + fstream input{ filename }; + vector data; + + for ( string line; getline(input, line); ) { + data.emplace_back(line); + } + + return data; +} + +bool +is_digit(char chr) +{ + return std::isdigit(static_cast(chr)) != 0; +} + +vector> +positions(size_t row, size_t col) +{ + return { + { row - 1, col - 1 }, + { row - 0, col - 1 }, + { row + 1, col - 1 }, + + { row - 1, col }, + { row + 1, col }, + + { row - 1, col + 1 }, + { row - 0, col + 1 }, + { row + 1, col + 1 }, + }; +} + +void +part1() // NOLINT +{ + auto lines = read_file("data/day03.txt"); + + auto is_symbol = [&lines](size_t row, size_t col) -> bool { + static const string symbols{ "*#+$%=-@&/" }; + + if ( row >= lines.size() || col >= lines[row].size() ) { + return false; + } + + auto symbol = lines[row][col]; + + return symbols.find(symbol) != string::npos; + }; + + auto bordering = [&is_symbol](size_t row, size_t col) -> bool { + bool result = false; + + for (const auto& position: positions(row, col)) { + result |= is_symbol(get<0>(position), get<1>(position)); + } + + return result; + }; + + auto sum = 0; + for ( size_t row = 0; row != lines.size(); ++row ) { + const auto& line = lines[row]; + + string::size_type start = 0; + while ( start != line.size() ) { + while ( start != line.size() && !is_digit(line[start]) ) { + ++start; + } + + auto end = start; + while ( end != line.size() && is_digit(line[end]) ) { + ++end; + } + + if ( start != end ) { + auto result = false; + + for ( auto col = start; col != end; ++col ) { + result |= bordering(row, col); + } + + if ( result ) { + sum += stoi(line.substr(start, end - start)); + } + + start = end; + } + } + } + cout << sum << endl; +} + +void +part2() // NOLINT +{ + auto lines = read_file("data/day03.txt"); + + auto find_integer = [](vector& lines, size_t row, size_t col, int& value) -> bool { // NOLINT + if ( row >= lines.size() || col >= lines[row].size() ) { + return false; + } + + auto& line = lines[row]; + + if ( !is_digit(line[col]) ) { + return false; + } + + // Anfang der Zahl suchen + auto start = col; + for ( ; start != 0 && is_digit(line[start - 1]); --start ) // NOLINT + ; + + auto end = col; + for ( ; end != line.size() && is_digit(line[end]); ++end ) // NOLINT + ; + + value = stoi(line.substr(start, end - start)); + + for ( ; start != end; ++start ) { + line[start] = '.'; + } + + return true; + }; + + auto sum = 0; + for ( size_t row = 0; row != lines.size(); ++row ) { + const auto& line = lines[row]; + + auto col = line.find('*'); + while ( col != string::npos ) { + vector values; + + auto lines_copy{ lines }; + + for ( const auto& position: positions(row, col) ) { + auto value = 0; + + if ( find_integer(lines_copy, get<0>(position), get<1>(position), value) ) { + values.emplace_back(value); + } + } + + if ( values.size() == 2 ) { + auto ratio = values[0] * values[1]; + sum += ratio; + } + + col = line.find('*', col + 1); + } + } + cout << sum << endl; +} + +int +main() +{ + part1(); + part2(); +} -- cgit v1.3