diff --git a/2022/puzzle-17-01.cc b/2022/puzzle-17-01.cc new file mode 100644 index 0000000..0ec18b8 --- /dev/null +++ b/2022/puzzle-17-01.cc @@ -0,0 +1,119 @@ +// +// Created by Matthew Gretton-Dann on 17/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; + +using namespace std::string_literals; +using Shape = std::vector; + +auto shapes_intersect(Shape const& tower, Shape const& shape, UInt x, UInt y) -> bool +{ + for (auto const& row : shape) { + UInt cx{x}; + for (auto const& c : row) { + if (c != ' ' && tower[y][cx] != '.') { + return true; + } + ++cx; + } + ++y; + } + return false; +} + +auto main() -> int +{ + std::string instructions; + if (!std::getline(std::cin, instructions)) { + std::cerr << "No input\n"; + return EXIT_FAILURE; + } + + UInt height{0}; + std::string const floor{"+-------+"}; + std::string const wall{"|.......|"}; + Shape const horiz = {{"oooo"}}; + Shape const plus = {{" o "}, {"ooo"}, {" o "}}; + Shape const corner = {{"ooo"}, {" o"}, {" o"}}; + Shape const vert = {{"o"}, {"o"}, {"o"}, {"o"}}; + Shape const square = {{"oo"}, {"oo"}}; + std::vector const shapes{horiz, plus, corner, vert, square}; + + Shape tower{floor}; + auto wind_it{instructions.begin()}; + auto shape_it{shapes.begin()}; + for (UInt i{0}; i < 2022; ++i) { + std::cout << " Shape " << i + 1 << " height: " << height << "\n"; + + // Where should the block appear? (2, 3 + height). + UInt x{3}; + UInt y{4 + height}; + + // Now make sure we have enough wall in the tower. + while (tower.size() < y + shape_it->size() + 1) { + tower.push_back(wall); + } + + // Now do the instructions in turn: + while (true) { + // Wind movement + UInt const trial_x{x + (*wind_it == '>' ? 1 : -1)}; + if (!shapes_intersect(tower, *shape_it, trial_x, y)) { + x = trial_x; + } + + ++wind_it; + if (wind_it == instructions.end()) { + wind_it = instructions.begin(); + } + + // Downward movement + UInt const trial_y{y - 1}; + if (!shapes_intersect(tower, *shape_it, x, trial_y)) { + y = trial_y; + } + else { + break; + } + } + + // Insert the piece. + for (auto const& r : *shape_it) { + UInt cx{x}; + for (auto c : r) { + if (c != ' ') { + tower[y][cx] = '#'; + } + ++cx; + } + ++y; + } + + // Now find the height. + height = tower.size() - 1; + while (tower[height].find("#") == std::string::npos) { + --height; + } + + // Next shape + ++shape_it; + if (shape_it == shapes.end()) { + shape_it = shapes.begin(); + } + } + std::cout << "Maximum height: " << height << "\n"; + return EXIT_SUCCESS; +}