diff --git a/2018/puzzle-13-01.cc b/2018/puzzle-13-01.cc new file mode 100644 index 0000000..d01323a --- /dev/null +++ b/2018/puzzle-13-01.cc @@ -0,0 +1,145 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; +using Point = std::pair; + +enum DirSelect { + left = 0, + straight = 1, + right = 2, +}; + +constexpr Point north{0, -1}; +constexpr Point east{1, 0}; +constexpr Point south{0, 1}; +constexpr Point west{-1, 0}; + +struct Truck +{ + Point pt_{0, 0}; + Point dir_{north}; + std::size_t dir_select_{0}; + UInt time_stamp_{0}; + + constexpr auto operator<(Truck const& r) const noexcept -> bool + { + return pt_.first < r.pt_.first || (pt_.first == r.pt_.first && pt_.second < r.pt_.second); + } +}; + +using State = std::set; + +auto main() -> int +{ + std::string line; + std::vector map; + State trucks; + + Point pos{0, 0}; + while (std::getline(std::cin, line)) { + for (auto& c : line) { + switch (c) { + case '>': + trucks.insert({pos, east, 0, 0}); + c = '-'; + break; + case '<': + trucks.insert({pos, west, 0, 0}); + c = '-'; + break; + case '^': + trucks.insert({pos, north, 0, 0}); + c = '|'; + break; + case 'v': + trucks.insert({pos, south, 0, 0}); + c = '|'; + break; + } + pos.first += 1; + } + map.push_back(line); + pos.first = 0; + pos.second += 1; + } + + UInt time_step{0}; + while (true) { + ++time_step; + std::cout << "\n" << std::setw(3) << time_step << ": "; + auto truck{trucks.begin()}; + while (truck != trucks.end()) { + if (truck->time_stamp_ >= time_step) { + ++truck; + continue; + } + std::cout << truck->pt_.first << "," << truck->pt_.second << ", "; + Point dir{truck->dir_}; + std::size_t dir_select = truck->dir_select_; + Point const pos{truck->pt_.first + dir.first, truck->pt_.second + dir.second}; + auto c{map.at(pos.second).at(pos.first)}; + switch (c) { + case '|': + case '-': + break; + case '/': + if (dir == west) { + dir = south; + } + else if (dir == south) { + dir = west; + } + else if (dir == east) { + dir = north; + } + else if (dir == north) { + dir = east; + } + break; + case '\\': + if (dir == west) { + dir = north; + } + else if (dir == north) { + dir = west; + } + else if (dir == east) { + dir = south; + } + else if (dir == south) { + dir = east; + } + break; + case '+': + if (dir_select == left) { + dir = Point{dir.second, -dir.first}; + } + else if (dir_select == right) { + dir = Point{-dir.second, dir.first}; + } + dir_select = (dir_select + 1) % 3; + break; + default: + abort(); + } + Truck const next_truck{pos, dir, dir_select, time_step}; + truck = trucks.erase(truck); + auto [next_it, success] = trucks.insert(next_truck); + if (!success) { + std::cout << "Crash at: " << pos.first << "," << pos.second << "\n"; + return EXIT_SUCCESS; + } + } + } +} diff --git a/2018/puzzle-13-02.cc b/2018/puzzle-13-02.cc new file mode 100644 index 0000000..818523d --- /dev/null +++ b/2018/puzzle-13-02.cc @@ -0,0 +1,149 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using UInt = std::uint64_t; +using Point = std::pair; + +enum DirSelect { + left = 0, + straight = 1, + right = 2, +}; + +constexpr Point north{0, -1}; +constexpr Point east{1, 0}; +constexpr Point south{0, 1}; +constexpr Point west{-1, 0}; + +struct Truck +{ + Point pt_{0, 0}; + Point dir_{north}; + std::size_t dir_select_{0}; + UInt time_stamp_{0}; + + constexpr auto operator<(Truck const& r) const noexcept -> bool + { + return pt_.first < r.pt_.first || (pt_.first == r.pt_.first && pt_.second < r.pt_.second); + } +}; + +using State = std::set; + +auto main() -> int +{ + std::string line; + std::vector map; + State trucks; + + Point pos{0, 0}; + while (std::getline(std::cin, line)) { + for (auto& c : line) { + switch (c) { + case '>': + trucks.insert({pos, east, 0, 0}); + c = '-'; + break; + case '<': + trucks.insert({pos, west, 0, 0}); + c = '-'; + break; + case '^': + trucks.insert({pos, north, 0, 0}); + c = '|'; + break; + case 'v': + trucks.insert({pos, south, 0, 0}); + c = '|'; + break; + } + pos.first += 1; + } + map.push_back(line); + pos.first = 0; + pos.second += 1; + } + + UInt time_step{0}; + while (trucks.size() > 1) { + ++time_step; + std::cout << "\n" << std::setw(3) << time_step << ": "; + auto truck{trucks.begin()}; + while (truck != trucks.end()) { + if (truck->time_stamp_ >= time_step) { + ++truck; + continue; + } + std::cout << truck->pt_.first << "," << truck->pt_.second << ", "; + Point dir{truck->dir_}; + std::size_t dir_select = truck->dir_select_; + Point const pos{truck->pt_.first + dir.first, truck->pt_.second + dir.second}; + auto c{map.at(pos.second).at(pos.first)}; + switch (c) { + case '|': + case '-': + break; + case '/': + if (dir == west) { + dir = south; + } + else if (dir == south) { + dir = west; + } + else if (dir == east) { + dir = north; + } + else if (dir == north) { + dir = east; + } + break; + case '\\': + if (dir == west) { + dir = north; + } + else if (dir == north) { + dir = west; + } + else if (dir == east) { + dir = south; + } + else if (dir == south) { + dir = east; + } + break; + case '+': + if (dir_select == left) { + dir = Point{dir.second, -dir.first}; + } + else if (dir_select == right) { + dir = Point{-dir.second, dir.first}; + } + dir_select = (dir_select + 1) % 3; + break; + default: + abort(); + } + Truck const next_truck{pos, dir, dir_select, time_step}; + truck = trucks.erase(truck); + auto [next_it, success] = trucks.insert(next_truck); + if (!success) { + std::cout << "Crash at: " << pos.first << "," << pos.second << "\n"; + trucks.erase(next_it); + truck = trucks.begin(); + } + } + } + + auto truck(trucks.begin()); + std::cout << "Point: " << truck->pt_.first << "," << truck->pt_.second << "\n"; +}