diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ca3748..56faaf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,9 +26,15 @@ target_link_libraries(day02 aocpp intcode) add_executable(day03 day03.cpp) target_link_libraries(day03 aocpp) +add_executable(day04 day04.cpp) +target_link_libraries(day04 aocpp) + add_executable(day05 day05.cpp) target_link_libraries(day05 aocpp intcode) +add_executable(day06 day06.cpp) +target_link_libraries(day06 aocpp) + add_executable(day07 day07.cpp) target_link_libraries(day07 aocpp intcode) diff --git a/day01.cpp b/day01.cpp index c1131ac..6fc766b 100644 --- a/day01.cpp +++ b/day01.cpp @@ -8,14 +8,14 @@ #include auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); + auto& in = aocpp::Startup(argc, argv); auto fuel = [](std::int64_t& x) { return x=x/3-2; }; std::int64_t x; std::int64_t part1 = 0; std::int64_t part2 = 0; - while (fin >> x) { + while (in >> x) { part1 += fuel(x); for (; x > 0; fuel(x)) { part2 += x; diff --git a/day02.cpp b/day02.cpp index eca052f..98d87f2 100644 --- a/day02.cpp +++ b/day02.cpp @@ -18,8 +18,7 @@ auto Compute(Machine machine, ValueType x, ValueType y) { } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machine = Machine{ParseStream(fin)}; + auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; std::cout << "Part 1: " << Compute(machine, 12, 2) << std::endl; diff --git a/day03.cpp b/day03.cpp index d6a5466..6464087 100644 --- a/day03.cpp +++ b/day03.cpp @@ -66,12 +66,12 @@ auto Record ( } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); + auto& in = aocpp::Startup(argc, argv); std::string line; - std::getline(fin, line); + std::getline(in, line); auto wire0 = BuildLine(line); - std::getline(fin, line); + std::getline(in, line); auto wire1 = BuildLine(line); std::map counts; diff --git a/day04.cpp b/day04.cpp new file mode 100644 index 0000000..9fd24fa --- /dev/null +++ b/day04.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +auto Parse(std::istream & in) -> std::pair { + std::int64_t lo, hi; + std::string line; + std::getline(in, line, '-'); + lo = std::stol(std::move(line)); + std::getline(in, line); + hi = std::stol(std::move(line)); + return {lo,hi}; +} + +auto Valid1(std::string const& str) { + for (std::size_t i = 1; i < str.size(); i++) { + if (str[i-1] == str[i]) { + return true; + } + } + return false; +} + +auto Valid2(std::string const& str) { + for (std::size_t i = 1; i < str.size(); i++) { + if ( str[i] == str[i-1] && + (i == str.size() - 1 || str[i] != str[i+1]) && + (i == 1 || str[i] != str[i-2])) + { + return true; + } + } + return false; +} + +} // namespace + +auto main(int argc, char** argv) -> int { + auto [lo,hi] = Parse(aocpp::Startup(argc, argv)); + + std::int64_t part1 = 0; + std::int64_t part2 = 0; + + for (auto i = lo; i <= hi; i++) { + auto str = std::to_string(i); + if (std::is_sorted(str.begin(), str.end())) { + if (Valid1(str)) part1++; + if (Valid2(str)) part2++; + } + } + + std::cout << "Part 1: " << part1 << std::endl; + std::cout << "Part 2: " << part2 << std::endl; +} diff --git a/day05.cpp b/day05.cpp index 19609b1..5dd5c59 100644 --- a/day05.cpp +++ b/day05.cpp @@ -18,8 +18,7 @@ auto Compute(Machine machine, ValueType d) -> ValueType { } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machine = Machine{ParseStream(fin)}; + auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; std::cout << "Part 1: " << Compute(machine, 1) << std::endl; std::cout << "Part 2: " << Compute(std::move(machine), 5) << std::endl; } diff --git a/day06.cpp b/day06.cpp new file mode 100644 index 0000000..af526dd --- /dev/null +++ b/day06.cpp @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +auto Parse(std::istream & in) { + std::map parents; + std::string line; + while (std::getline(in, line)) { + auto it = line.find(')'); + if (it == std::string::npos) throw std::runtime_error{"bad input entry"}; + parents.insert({line.substr(it+1), line.substr(0, it)}); + } + + return parents; +} + +auto Path(std::map const& parents, std::string const& start) +{ + std::vector path; + std::string const* name = &start; + while (*name != "COM") { + name = &parents.at(*name); + path.push_back(*name); + } + return path; +} + +auto Part1(std::map const& parents) { + std::map depths {{"COM", 0}}; + std::size_t part1 {0}; + + for (auto & [k, _] : parents) { + + std::string const* cursor = &k; + std::vector todo; + + decltype(depths)::iterator it; + while (depths.end() == (it = depths.find(*cursor))) { + todo.push_back(cursor); + cursor = &parents.at(*cursor); + } + auto n = it->second; + + for (; !todo.empty(); todo.pop_back()) { + depths[*todo.back()] = ++n; + } + + part1 += n; + } + + + return part1; +} + +auto Part2(std::map const& parents) { + auto p1 = Path(parents, "SAN"); + auto p2 = Path(parents, "YOU"); + + while (p1.back() == p2.back()) { + p1.pop_back(); + p2.pop_back(); + } + + return p1.size() + p2.size(); +} + +} // namespace + +auto main(int argc, char** argv) -> int { + auto parents = Parse(aocpp::Startup(argc, argv)); + std::cout << "Part 1: " << Part1(parents) << std::endl; + std::cout << "Part 2: " << Part2(parents) << std::endl; +} diff --git a/day07.cpp b/day07.cpp index 2b2c3b1..ff5eeb3 100644 --- a/day07.cpp +++ b/day07.cpp @@ -62,8 +62,7 @@ auto optimize(Machine machine, std::vector params, F f) { } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machine = Machine{ParseStream(fin)}; + auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; std::cout << "Part 1: " << optimize(machine, {0, 1, 2, 3, 4}, compute1) << std::endl; std::cout << "Part 2: " << optimize(std::move(machine), {5, 6, 7, 8, 9}, compute2) << std::endl; } diff --git a/day09.cpp b/day09.cpp index f59db69..fa17471 100644 --- a/day09.cpp +++ b/day09.cpp @@ -18,8 +18,7 @@ auto Compute(Machine machine, ValueType d) -> ValueType { } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machine = Machine{ParseStream(fin)}; + auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; std::cout << "Part 1: " << Compute(machine, 1) << std::endl; std::cout << "Part 2: " << Compute(std::move(machine), 2) << std::endl; } diff --git a/day11.cpp b/day11.cpp index 2455bad..66aefb2 100644 --- a/day11.cpp +++ b/day11.cpp @@ -38,8 +38,7 @@ auto Compute(Machine machine, ValueType start) } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machine = Machine{ParseStream(fin)}; + auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; std::cout << "Part 1: " << Compute(machine, 0).size() << "\nPart 2\n"; Draw(std::cout, Compute(std::move(machine), 1)); } diff --git a/day13.cpp b/day13.cpp index b90f301..0bd3048 100644 --- a/day13.cpp +++ b/day13.cpp @@ -60,8 +60,7 @@ auto Compute2(Machine machine) { } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machine = Machine{ParseStream(fin)}; + auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; std::cout << "Part 1: " << Compute1(machine) << std::endl; std::cout << "Part 2: " << Compute2(std::move(machine)) << std::endl; } diff --git a/day15.cpp b/day15.cpp index 9f290bc..d6cab80 100644 --- a/day15.cpp +++ b/day15.cpp @@ -91,8 +91,7 @@ auto Compute(std::map world) -> std::pair { } // namespace auto main(int argc, char** argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto [p1,p2] = Compute(Explore(Machine{ParseStream(fin)})); + auto [p1,p2] = Compute(Explore(Machine{ParseStream(aocpp::Startup(argc, argv))})); std::cout << "Part 1: " << p1 << std::endl; std::cout << "Part 2: " << p2 << std::endl; } diff --git a/day23.cpp b/day23.cpp index 5e1481c..75560a3 100644 --- a/day23.cpp +++ b/day23.cpp @@ -56,8 +56,7 @@ auto Interact(Ethernet & ethernet, Machine & m, std::optional p) -> voi } // namespace auto main(int const argc, char** const argv) -> int { - auto fin = aocpp::Startup(argc, argv); - auto machines = BuildNetwork(Machine{ParseStream(fin)}); + auto machines = BuildNetwork(Machine{ParseStream(aocpp::Startup(argc, argv))}); auto ethernet = Ethernet{}; std::optional part1; diff --git a/lib/include/aocpp/Startup.hpp b/lib/include/aocpp/Startup.hpp index c527c24..3b007d8 100644 --- a/lib/include/aocpp/Startup.hpp +++ b/lib/include/aocpp/Startup.hpp @@ -2,9 +2,12 @@ #define AOCPP_STARTUP_HPP_ #include +#include +#include namespace aocpp { -auto Startup(int argc, char ** argv) -> std::ifstream; + +auto Startup(int argc, char ** argv) -> std::istream&; } #endif diff --git a/lib/src/Startup.cpp b/lib/src/Startup.cpp index c12197c..14f6eee 100644 --- a/lib/src/Startup.cpp +++ b/lib/src/Startup.cpp @@ -2,16 +2,21 @@ #include #include +#include +#include #include namespace aocpp { -auto Startup(int argc, char ** argv) -> std::ifstream { - if (argc != 2) { - std::cerr << "Expected input file argument\n"; +auto Startup(int argc, char ** argv) -> std::istream& { + static std::ifstream fin; + switch (argc) { + case 2: fin = std::ifstream{argv[1]}; return fin; + case 1: return std::cin; + default: + std::cerr << "bad arguments\n"; exit(EXIT_FAILURE); } - return std::ifstream{argv[1]}; } }