2017-12
This commit is contained in:
		
							
								
								
									
										39
									
								
								2017/11.cpp
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								2017/11.cpp
									
									
									
									
									
								
							| @@ -10,43 +10,12 @@ | ||||
|  | ||||
| #include <aocpp/Startup.hpp> | ||||
| #include <aocpp/Parsing.hpp> | ||||
| #include <aocpp/Hex.hpp> | ||||
|  | ||||
| using namespace aocpp; | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| /* | ||||
|   \ n  / | ||||
| nw +--+ ne | ||||
|   /    \ | ||||
| -+      +- | ||||
|   \    / | ||||
| sw +--+ se | ||||
|   / s  \ | ||||
| */ | ||||
|  | ||||
| struct Hex { | ||||
|   std::int64_t q, r, s; | ||||
| }; | ||||
|  | ||||
| constexpr Hex HEX_N  {  0, -1,  1 }; | ||||
| constexpr Hex HEX_NE {  1, -1,  0 }; | ||||
| constexpr Hex HEX_SE {  1,  0, -1 }; | ||||
| constexpr Hex HEX_S  {  0,  1, -1 }; | ||||
| constexpr Hex HEX_SW { -1,  1,  0 }; | ||||
| constexpr Hex HEX_NW { -1,  0,  1 }; | ||||
|  | ||||
| auto operator+(Hex a, Hex b) -> Hex { | ||||
|   return {a.q + b.q, a.r + b.r, a.s + b.s }; | ||||
| } | ||||
|  | ||||
| auto operator+=(Hex & a, Hex b) -> Hex & { | ||||
|   a.q += b.q; a.r += b.r; a.s += b.s; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| auto hex_distance(Hex hex) -> std::int64_t { | ||||
|   return (std::abs(hex.q) + std::abs(hex.r) + std::abs(hex.s)) / 2; | ||||
| } | ||||
|  | ||||
| auto Walk(std::string const& commands) | ||||
| -> std::pair<std::int64_t, std::int64_t> | ||||
| { | ||||
| @@ -93,7 +62,7 @@ TEST_SUITE("2017-11 examples") { | ||||
|  | ||||
| auto main(int argc, char** argv) -> int { | ||||
|   std::string line; | ||||
|   std::getline(*aocpp::Startup(argc, argv), line); | ||||
|   std::getline(*Startup(argc, argv), line); | ||||
|   auto [part1, part2] = Walk(line); | ||||
|   std::cout << "Part 1: " << part1 << std::endl; | ||||
|   std::cout << "Part 2: " << part2 << std::endl; | ||||
|   | ||||
							
								
								
									
										109
									
								
								2017/12.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								2017/12.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| #include <cstdint> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <tuple> | ||||
|  | ||||
| #include <doctest.h> | ||||
|  | ||||
| #include <aocpp/Startup.hpp> | ||||
|  | ||||
| using namespace aocpp; | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| auto Parse(std::istream & in) | ||||
| -> std::vector<std::vector<std::uint16_t>> | ||||
| { | ||||
|   std::string line; | ||||
|   std::vector<std::vector<std::uint16_t>> result; | ||||
|   while (std::getline(in, line)) { | ||||
|     line.erase(std::remove_if(line.begin(), line.end(), [](auto c) { | ||||
|       return c=='<' || c=='-' || c=='>' || c == ','; | ||||
|     }), line.end()); | ||||
|     std::istringstream lin { line }; | ||||
|     std::uint16_t x; | ||||
|     lin >> x; | ||||
|     std::vector<std::uint16_t> links; | ||||
|     while (lin >> x) { | ||||
|       links.push_back(x); | ||||
|     } | ||||
|     result.emplace_back(std::move(links)); | ||||
|   } | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| auto Find(std::vector<std::uint16_t> & leaders, std::uint16_t const who) -> std::uint16_t | ||||
| { | ||||
|   std::uint16_t cursor; | ||||
|   std::uint16_t leader = who; | ||||
|  | ||||
|   do { | ||||
|     cursor = leader; | ||||
|     leader = leaders[cursor]; | ||||
|   } while (leader != cursor); | ||||
|  | ||||
|   cursor = who; | ||||
|   while (cursor != leader) { | ||||
|     auto tmp = leaders[cursor]; | ||||
|     leaders[cursor] = leader; | ||||
|     cursor = tmp; | ||||
|   } | ||||
|  | ||||
|   return leader; | ||||
| } | ||||
|  | ||||
| auto LinkNodes(std::vector<std::vector<std::uint16_t>> const& input) | ||||
| -> std::pair<std::size_t, std::size_t> | ||||
| { | ||||
|   // Allocate leaders array and assign each node as its own leader | ||||
|   std::vector<std::uint16_t> leaders(input.size()); | ||||
|   for (std::size_t i = 0; i < leaders.size(); i++) { | ||||
|     leaders[i] = i; | ||||
|   } | ||||
|  | ||||
|   // Link up all the nodes as specified in the input file | ||||
|   for (std::size_t i = 0; i < input.size(); i++) { | ||||
|     auto x_ = Find(leaders, i); | ||||
|     for (auto const y : input[i]) { | ||||
|       leaders[Find(leaders,y)] = x_; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   std::size_t part1 = 0; | ||||
|   std::size_t part2 = 0; | ||||
|  | ||||
|   auto target1 = Find(leaders, 0); | ||||
|   for (std::size_t i = 0; i < leaders.size(); i++) { | ||||
|     if (Find(leaders, i) == target1) part1++; | ||||
|     if (leaders[i] == i) part2++; | ||||
|   } | ||||
|  | ||||
|   return {part1, part2}; | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
|  | ||||
| TEST_SUITE("2017-12 examples") { | ||||
|   TEST_CASE("example") { | ||||
|     std::istringstream in { | ||||
|       "0 <-> 2\n" | ||||
|       "1 <-> 1\n" | ||||
|       "2 <-> 0, 3, 4\n" | ||||
|       "3 <-> 2, 4\n" | ||||
|       "4 <-> 2, 3, 6\n" | ||||
|       "5 <-> 6\n" | ||||
|       "6 <-> 4, 5\n"}; | ||||
|     auto [p1,p2] = LinkNodes(Parse(in)); | ||||
|     CHECK(p1 == 6); | ||||
|     CHECK(p2 == 2); | ||||
|   } | ||||
| } | ||||
|  | ||||
| auto main(int argc, char** argv) -> int { | ||||
|   auto input = Parse(*Startup(argc, argv)); | ||||
|   auto [part1, part2] = LinkNodes(input); | ||||
|   std::cout << "Part 1: " << part1 << std::endl; | ||||
|   std::cout << "Part 2: " << part2 << std::endl; | ||||
| } | ||||
| @@ -10,6 +10,9 @@ target_link_libraries(2017_10 aocpp knothash) | ||||
| add_executable(2017_11 11.cpp) | ||||
| target_link_libraries(2017_11 aocpp) | ||||
|  | ||||
| add_executable(2017_12 12.cpp) | ||||
| target_link_libraries(2017_12 aocpp) | ||||
|  | ||||
| add_executable(2017_14 14.cpp) | ||||
| target_link_libraries(2017_14 aocpp knothash) | ||||
|  | ||||
|   | ||||
							
								
								
									
										57
									
								
								lib/include/aocpp/Hex.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								lib/include/aocpp/Hex.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| #ifndef AOCPP_HEX_HPP_ | ||||
| #define AOCPP_HEX_HPP_ | ||||
|  | ||||
| #include <numeric> | ||||
| #include <cstdint> | ||||
|  | ||||
| namespace aocpp { | ||||
| /* | ||||
|   \ n  / | ||||
| nw +--+ ne | ||||
|   /    \ | ||||
| -+      +- | ||||
|   \    / | ||||
| sw +--+ se | ||||
|   / s  \ | ||||
| */ | ||||
|  | ||||
| struct Hex { | ||||
|   std::int64_t q, r, s; | ||||
| }; | ||||
|  | ||||
| constexpr Hex HEX_N  {  0, -1,  1 }; | ||||
| constexpr Hex HEX_NE {  1, -1,  0 }; | ||||
| constexpr Hex HEX_SE {  1,  0, -1 }; | ||||
| constexpr Hex HEX_S  {  0,  1, -1 }; | ||||
| constexpr Hex HEX_SW { -1,  1,  0 }; | ||||
| constexpr Hex HEX_NW { -1,  0,  1 }; | ||||
|  | ||||
| auto operator+(Hex const& a, Hex const& b) -> Hex { | ||||
|   return {a.q + b.q, a.r + b.r, a.s + b.s }; | ||||
| } | ||||
|  | ||||
| auto operator+=(Hex & a, Hex const& b) -> Hex & { | ||||
|   a.q += b.q; a.r += b.r; a.s += b.s; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| auto operator-(Hex const& a, Hex const& b) -> Hex { | ||||
|   return {a.q - b.q, a.r - b.r, a.s - b.s }; | ||||
| } | ||||
|  | ||||
| auto operator-=(Hex & a, Hex const& b) -> Hex & { | ||||
|   a.q -= b.q; a.r -= b.r; a.s -= b.s; | ||||
|   return a; | ||||
| } | ||||
|  | ||||
| auto operator-(Hex const& a) -> Hex { | ||||
|   return {-a.q, -a.r, -a.s }; | ||||
| } | ||||
|  | ||||
| auto hex_distance(Hex hex) -> std::int64_t { | ||||
|   return (std::abs(hex.q) + std::abs(hex.r) + std::abs(hex.s)) / 2; | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user