From ae1e96f10b399266825e275ca4a8100ceede9cad Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Thu, 23 Oct 2025 19:28:20 +0200 Subject: days 19-25, aoc 2016 --- 2016/src/day21.cpp | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 2016/src/day21.cpp (limited to '2016/src/day21.cpp') diff --git a/2016/src/day21.cpp b/2016/src/day21.cpp new file mode 100644 index 0000000..7e8fed7 --- /dev/null +++ b/2016/src/day21.cpp @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace { + +void +swap_at_pos(string& str, size_t x, size_t y) +{ + if ( str.empty() ) { + return; + } + + swap(str.at(x), str.at(y)); +} + +void +swap_letter(string& str, char x, char y) +{ + if ( str.empty() ) { + return; + } + + for ( auto& chr: str ) { + if ( chr == x ) { + chr = y; + } + else if ( chr == y ) { + chr = x; + } + } +} + +void +rotate_left(string& str, size_t n) +{ + if ( str.empty() ) { + return; + } + + ranges::rotate(str, str.begin() + static_cast(n % str.size())); +} + +void +rotate_right(string& str, size_t n) +{ + if ( str.empty() ) { + return; + } + + rotate_left(str, str.size() - n); +} + +void +rotate(string& str, char chr) +{ + if ( str.empty() ) { + return; + } + + const auto idx = str.find(chr); + if ( idx == string::npos ) { + return; + } + + const auto steps = 1 + idx + (idx >= 4 ? 1 : 0); + rotate_right(str, steps % str.size()); +} + +void +reverse(string& str, size_t x, size_t y) +{ + if ( str.empty() ) { + return; + } + + if ( x > y ) { + swap(x, y); + } + + reverse(str.begin() + static_cast(x), + str.begin() + static_cast(y) + 1); +} + +void +move(string& str, size_t x, size_t y) +{ + if ( str.empty() ) { + return; + } + + const auto chr = str.at(x); + + str.erase(x, 1); + str.insert(y, 1, chr); +} + +vector +readLines(const filesystem::path& filename) +{ + ifstream file{ filename }; + vector lines; + + for ( string line; getline(file, line); ) { + lines.emplace_back(line); + } + + return lines; +} + +vector +split(const string& line, char sep = ' ') +{ + vector words; + stringstream input{ line }; + + for ( string word; getline(input, word, sep); ) { + words.emplace_back(word); + } + + return words; +} + +void +part1(const vector& lines, string str) +{ + for ( const auto& line: lines ) { + auto words = split(line); + + if ( line.starts_with("swap position") ) { + swap_at_pos(str, stoull(words.at(2)), stoull(words.at(5))); + } + else if ( line.starts_with("swap letter") ) { + swap_letter(str, words.at(2).at(0), words.at(5).at(0)); + } + else if ( line.starts_with("rotate left") ) { + rotate_left(str, stoull(words.at(2))); + } + else if ( line.starts_with("rotate right") ) { + rotate_right(str, stoull(words.at(2))); + } + else if ( line.starts_with("rotate based") ) { + rotate(str, words.at(6).at(0)); + } + else if ( line.starts_with("reverse") ) { + reverse(str, stoull(words.at(2)), stoull(words.at(4))); + } + else if ( line.starts_with("move") ) { + move(str, stoull(words.at(2)), stoull(words.at(5))); + } + else { + cerr << "unknown command: " << line << '\n'; + return; + } + } + cout << str << '\n'; +} + +void +part2(const vector& lines, string str) +{ + for ( const auto& line: ranges::reverse_view(lines) ) { + auto words = split(line); + + if ( line.starts_with("swap position") ) { + swap_at_pos(str, stoull(words.at(2)), stoull(words.at(5))); + } + else if ( line.starts_with("swap letter") ) { + swap_letter(str, words.at(2).at(0), words.at(5).at(0)); + } + else if ( line.starts_with("rotate left") ) { + rotate_right(str, stoull(words.at(2))); + } + else if ( line.starts_with("rotate right") ) { + rotate_left(str, stoull(words.at(2))); + } + else if ( line.starts_with("rotate based") ) { + auto chr = words.at(6).at(0); + for ( size_t i = 0; i != str.size(); ++i ) { + string tmp = str; + rotate_left(tmp, i); + + auto idx = tmp.find(chr); + auto steps = (1 + idx + (idx >= 4 ? 1 : 0)); + + if ( ((steps - i + str.size()) % str.size()) == 0 ) { + str = tmp; + break; + } + } + } + else if ( line.starts_with("reverse") ) { + reverse(str, stoull(words.at(2)), stoull(words.at(4))); + } + else if ( line.starts_with("move") ) { + move(str, stoull(words.at(5)), stoull(words.at(2))); + } + else { + cerr << "unknown command: " << line << '\n'; + return; + } + } + cout << str << '\n'; +} + +} // namespace + +int +main() +{ + auto lines = readLines("data/day21.txt"); + + part1(lines, "abcdefgh"); + part2(lines, "fbgdceah"); +} -- cgit v1.3