diff --git a/CMakeLists.txt b/CMakeLists.txt index 8605f97..4801ba0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,14 @@ project(aocpp19 LANGUAGES C CXX ) +include(CheckIPOSupported) +check_ipo_supported(RESULT result OUTPUT output) +if(result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +else() + message(WARNING "IPO is not supported: ${output}") +endif() + add_subdirectory(lib) add_executable(day02 day02.cpp) diff --git a/day11.cpp b/day11.cpp index fc0dae9..5d7315f 100644 --- a/day11.cpp +++ b/day11.cpp @@ -4,19 +4,17 @@ #include #include +#include using namespace intcode; namespace { -using Coord = std::pair; - auto Compute(Machine machine, ValueType start) -> std::map { Coord here {0,0}; std::map paint {{here,start}}; - ValueType dx {0}; - ValueType dy {-1}; + Coord dir {0, -1}; bool next_color = true; @@ -26,10 +24,8 @@ auto Compute(Machine machine, ValueType start) if (next_color) { paint[here] = o; } else { - std::swap(dx, dy); - (o ? dx : dy) *= -1; - here.first += dx; - here.second += dy; + dir = (o ? CW : CCW)(dir); + here = Add(here, dir); } next_color = !next_color; }); @@ -37,23 +33,6 @@ auto Compute(Machine machine, ValueType start) return paint; } -auto Draw(std::ostream & out, std::map image) { - ValueType minX = 0, maxX = 0, minY = 0, maxY = 0; - for (auto&& [k, _] : image) { - auto [x,y] = k; - minX = std::min(minX, x); - maxX = std::max(maxX, x); - minY = std::min(minY, y); - maxY = std::max(maxY, y); - } - for (ValueType y = minY; y <= maxY; y++) { - for (ValueType x = minX; x <= maxX; x++) { - out << (image[{x,y}] ? "▓" : "░"); - } - out << "\n"; - } -} - } // namespace auto main() -> int { diff --git a/day13.cpp b/day13.cpp index 52db32d..02f150e 100644 --- a/day13.cpp +++ b/day13.cpp @@ -4,12 +4,11 @@ #include #include +#include using namespace intcode; namespace { -using Coord = std::pair; - auto Compute1(Machine machine) -> std::size_t { std::set screen; diff --git a/day15.cpp b/day15.cpp index 1c2b344..9753cb9 100644 --- a/day15.cpp +++ b/day15.cpp @@ -1,85 +1,65 @@ -#include -#include -#include -#include -#include #include -#include +#include +#include +#include +#include #include +#include using namespace intcode; namespace { -using Coord = std::pair; +std::pair const moves[4] + {{1, Up}, {2, Down}, {3, Left}, {4, Right}}; -auto Compute(Machine machine) -> std::pair { - Coord here {0,0}; - std::map world {{{0,0},1}}; +auto Fork(Machine m, ValueType cmd) { + std::get(Step(m)).pos = cmd; + auto o = std::get(Step(m)).val; + return std::make_pair(o, std::move(m)); +} - using State = std::tuple; +auto Compute(Machine machine) { + Coord const origin {0,0}; + std::set world {origin}; - std::vector layer {{{0,0}, std::move(machine)}}; - std::vector next_layer; + std::deque> todo + {{0, origin, std::move(machine)}}; - auto action = [&](Machine m, ValueType cmd, Coord coord) { - if (!world.contains(coord)) { - std::get(Step(m)).pos = cmd; - auto o = std::get(Step(m)).val; - world[coord] = o; - if (o) { - next_layer.emplace_back(coord, std::move(m)); + long part1 = -1; + long part2 = -1; + +top: + while (!todo.empty()) { + auto & [steps, loc, m] = todo.front(); + part2 = steps; + steps++; + + for (auto&& [cmd, fun] : moves) { + auto loc_ = fun(loc); + if (world.insert(loc_).second) { + auto [o,m_] = Fork(m, cmd); + switch (o) { + case 2: + part1 = steps; + world = {origin}; + todo = {{0, origin, std::move(m_)}}; + goto top; + case 1: + todo.emplace_back(steps, loc_, std::move(m_)); + } } } - }; - - int part1 = 0; - while (!layer.empty()) { - for (auto && s : layer) { - auto& [loc, m] = s; - if (2 == world[loc]) { - world.clear(); - world[loc] = 2; - auto start = std::move(m); - layer.clear(); - layer.push_back({loc, std::move(start)}); - goto loop2; - } - auto [x,y] = loc; - action(m, 1, {x,y-1}); - action(m, 2, {x,y+1}); - action(m, 3, {x-1,y}); - action(std::move(m), 4, {x+1,y}); - } - layer = std::move(next_layer); - next_layer.clear(); - part1++; + todo.pop_front(); } - -loop2: - int part2 = 0; - while (!layer.empty()) { - for (auto && s : layer) { - auto& [loc, m] = s; - auto [x,y] = loc; - action(m, 1, {x,y-1}); - action(m, 2, {x,y+1}); - action(m, 3, {x-1,y}); - action(std::move(m), 4, {x+1,y}); - } - layer = std::move(next_layer); - next_layer.clear(); - part2++; - } - return {part1, part2-1}; + return std::make_pair(part1,part2); } } // namespace auto main() -> int { - auto machine = Machine{ParseStream(std::cin)}; - auto [part1, part2] = Compute(machine); + auto [part1, part2] = Compute(Machine{ParseStream(std::cin)}); std::cout << "Part 1: " << part1 << std::endl; std::cout << "Part 2: " << part2 << std::endl; } diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index e10e3fc..8a44164 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,2 +1,2 @@ -add_library(intcode src/Parser.cpp src/Interpreter.cpp src/Machine.cpp) +add_library(intcode src/Grid.cpp src/Parser.cpp src/Interpreter.cpp src/Machine.cpp) target_include_directories(intcode PUBLIC include) diff --git a/lib/include/intcode/intcode.hpp b/lib/include/intcode/intcode.hpp index 7506259..fb11a8f 100644 --- a/lib/include/intcode/intcode.hpp +++ b/lib/include/intcode/intcode.hpp @@ -1,9 +1,9 @@ #ifndef INTCODE_INTCODE_HPP_ #define INTCODE_INTCODE_HPP_ +#include #include #include -#include #include #endif