This commit is contained in:
Eric Mertens 2022-11-25 10:55:28 -08:00
parent 3e56891071
commit d041919d91
4 changed files with 173 additions and 35 deletions

View File

@ -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
View 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;
}

View File

@ -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
View 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