1+ #include " common.h"
2+
3+ namespace {
4+ struct Move {
5+ long qty;
6+ long src;
7+ long dst;
8+ };
9+
10+ auto parse (const auto &input) {
11+ enum class mode { stack, move };
12+ mode m{mode::stack};
13+ std::vector<std::deque<char >> sts (10 );
14+ std::vector<Move> mvs{};
15+ for (const auto &l : input) {
16+ if (l.empty ()) {
17+ m = mode::move;
18+ continue ;
19+ }
20+ if (l[1 ] == ' 1' ) {
21+ continue ;
22+ }
23+ if (m == mode::stack) {
24+ for (size_t i = 1 ; i < l.size (); i += 4 ) {
25+ if (l[i] != ' ' )
26+ sts[static_cast <int >(i / 4 )].push_front (l[i]);
27+ }
28+ } else if (m == mode::move) {
29+ Move mv{};
30+ sscanf (l.c_str (), " move %ld from %ld to %ld" , &mv.qty , &mv.src , &mv.dst );
31+ --mv.src ;
32+ --mv.dst ;
33+ mvs.emplace_back (std::move (mv));
34+ }
35+ }
36+ return std::move (make_tuple (sts, mvs));
37+ }
38+
39+ std::string p1 (const auto &input) {
40+ auto [sts, mvs] = parse (input);
41+ for (auto mv : mvs) {
42+ while (mv.qty --) {
43+ sts[mv.dst ].push_back (sts[mv.src ].back ());
44+ sts[mv.src ].pop_back ();
45+ }
46+ }
47+ std::ostringstream out;
48+ for (const auto &st : sts) {
49+ if (st.size ())
50+ out << st.back ();
51+ }
52+ return out.str ();
53+ }
54+
55+ std::string p2 (const auto &input) {
56+ auto [sts, mvs] = parse (input);
57+ for (auto mv : mvs) {
58+ std::stack<char > t;
59+ while (mv.qty --) {
60+ t.push (sts[mv.src ].back ());
61+ sts[mv.src ].pop_back ();
62+ }
63+ while (t.size ()) {
64+ sts[mv.dst ].push_back (t.top ());
65+ t.pop ();
66+ }
67+ }
68+ std::ostringstream out;
69+ for (const auto &st : sts) {
70+ if (st.size ())
71+ out << st.back ();
72+ }
73+ return out.str ();
74+ }
75+ } // namespace
76+
77+ int main () {
78+ const auto &input = gb::advent2021::readIn ();
79+ gb::advent2021::writeOut (p1 (input));
80+ gb::advent2021::writeOut (p2 (input));
81+ }
0 commit comments