cleanups
This commit is contained in:
parent
930a02622d
commit
a38a105e6f
|
@ -2,6 +2,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <stdexcept>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
37
2022/16.cpp
37
2022/16.cpp
|
@ -12,6 +12,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stack>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -90,8 +91,8 @@ struct Room {
|
||||||
/// * Valve **name** has flow rate= **number** ; tunnel leads to valve **name**
|
/// * Valve **name** has flow rate= **number** ; tunnel leads to valve **name**
|
||||||
auto Parse(std::istream & in) -> std::vector<Room>
|
auto Parse(std::istream & in) -> std::vector<Room>
|
||||||
{
|
{
|
||||||
std::vector<Room> result;
|
auto result = std::vector<Room>{};
|
||||||
std::string line;
|
auto line = std::string{};
|
||||||
while (std::getline(in, line)) {
|
while (std::getline(in, line)) {
|
||||||
using namespace qi::labels;
|
using namespace qi::labels;
|
||||||
using It = std::string::const_iterator;
|
using It = std::string::const_iterator;
|
||||||
|
@ -108,8 +109,8 @@ auto Parse(std::istream & in) -> std::vector<Room>
|
||||||
" " >>
|
" " >>
|
||||||
(name % ", ") [ phx::bind(&Room::connections, _val) = _1 ];
|
(name % ", ") [ phx::bind(&Room::connections, _val) = _1 ];
|
||||||
|
|
||||||
It b = line.begin();
|
auto b = line.cbegin();
|
||||||
It const e = line.end();
|
auto const e = line.cend();
|
||||||
result.emplace_back();
|
result.emplace_back();
|
||||||
if (!qi::parse(b, e, room_description, result.back()) || b != e) {
|
if (!qi::parse(b, e, room_description, result.back()) || b != e) {
|
||||||
throw std::runtime_error{"bad input line"};
|
throw std::runtime_error{"bad input line"};
|
||||||
|
@ -138,15 +139,15 @@ auto GenerateDistances(
|
||||||
std::vector<Room> const& rooms
|
std::vector<Room> const& rooms
|
||||||
) -> std::pair<std::size_t, distance_array<std::uint64_t>>
|
) -> std::pair<std::size_t, distance_array<std::uint64_t>>
|
||||||
{
|
{
|
||||||
auto const N {rooms.size()};
|
auto const N = rooms.size();
|
||||||
|
|
||||||
// Associate the names and indexes of each room
|
// Associate the names and indexes of each room
|
||||||
std::unordered_map<std::string, std::size_t> names;
|
std::unordered_map<std::string, std::size_t> names;
|
||||||
for (auto [i,room] : rooms | boost::adaptors::indexed()) {
|
for (auto const [i,room] : boost::adaptors::index(rooms)) {
|
||||||
names[room.name] = i;
|
names[room.name] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
distance_array<std::uint64_t> distances{boost::extents[N][N]};
|
auto distances = distance_array<std::uint64_t>{boost::extents[N][N]};
|
||||||
|
|
||||||
for (auto const i : boost::irange(rooms.size())) {
|
for (auto const i : boost::irange(rooms.size())) {
|
||||||
auto di = distances[i];
|
auto di = distances[i];
|
||||||
|
@ -201,13 +202,15 @@ auto Routes(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximal flow seen at each set of open valves
|
// Maximal flow seen at each set of open valves
|
||||||
std::unordered_map<Valves, std::uint64_t> result;
|
auto result = std::unordered_map<Valves, std::uint64_t>{};
|
||||||
|
|
||||||
// Remaining states for depth first search
|
// Remaining states for depth first search
|
||||||
std::vector<State> states {{initial_time, 0, start, {}}};
|
auto states = std::stack<State>{};
|
||||||
|
states.push({initial_time, 0, start, {}});
|
||||||
|
|
||||||
while (!states.empty()) {
|
while (!states.empty()) {
|
||||||
auto const state = states.back();
|
auto const state = states.top();
|
||||||
states.pop_back();
|
states.pop();
|
||||||
|
|
||||||
if (auto & best = result[state.valves]; best < state.flow) {
|
if (auto & best = result[state.valves]; best < state.flow) {
|
||||||
best = state.flow;
|
best = state.flow;
|
||||||
|
@ -215,7 +218,7 @@ auto Routes(
|
||||||
|
|
||||||
auto const distances_i = distances[state.location];
|
auto const distances_i = distances[state.location];
|
||||||
|
|
||||||
for (auto const [j, room] : rooms | boost::adaptors::indexed()) {
|
for (auto const [j, room] : boost::adaptors::index(rooms)) {
|
||||||
// don't revisit a valve
|
// don't revisit a valve
|
||||||
if (state.valves.test(j)) { continue; }
|
if (state.valves.test(j)) { continue; }
|
||||||
|
|
||||||
|
@ -229,7 +232,7 @@ auto Routes(
|
||||||
auto valves = state.valves;
|
auto valves = state.valves;
|
||||||
valves.set(j);
|
valves.set(j);
|
||||||
|
|
||||||
states.push_back({time, flow, static_cast<std::size_t>(j), valves});
|
states.push({time, flow, static_cast<std::size_t>(j), valves});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +268,7 @@ auto Part2(
|
||||||
auto const routes = Routes(start, 26, rooms, distances);
|
auto const routes = Routes(start, 26, rooms, distances);
|
||||||
auto const end = routes.end();
|
auto const end = routes.end();
|
||||||
|
|
||||||
std::uint64_t best {0};
|
auto best = std::uint64_t{0};
|
||||||
for (auto it1 = routes.begin(); it1 != end; ++it1) {
|
for (auto it1 = routes.begin(); it1 != end; ++it1) {
|
||||||
for (auto it2 = std::next(it1); it2 != end; ++it2) {
|
for (auto it2 = std::next(it1); it2 != end; ++it2) {
|
||||||
// only consider pairs that have disjoint sets of valves
|
// only consider pairs that have disjoint sets of valves
|
||||||
|
@ -285,7 +288,7 @@ auto Part2(
|
||||||
auto Main(std::istream & in, std::ostream & out) -> void
|
auto Main(std::istream & in, std::ostream & out) -> void
|
||||||
{
|
{
|
||||||
auto rooms = Parse(in);
|
auto rooms = Parse(in);
|
||||||
auto const n = FlowsFirst(rooms);
|
auto const n = FlowsFirst(rooms); // reorders rooms
|
||||||
auto const [start, distances] = GenerateDistances(rooms);
|
auto const [start, distances] = GenerateDistances(rooms);
|
||||||
rooms.resize(n); // forget about the rooms with no flow
|
rooms.resize(n); // forget about the rooms with no flow
|
||||||
out << "Part 1: " << Part1(start, rooms, distances) << std::endl;
|
out << "Part 1: " << Part1(start, rooms, distances) << std::endl;
|
||||||
|
@ -306,13 +309,13 @@ Valve HH has flow rate=22; tunnel leads to valve GG
|
||||||
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||||
Valve JJ has flow rate=21; tunnel leads to valve II
|
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||||
)"};
|
)"};
|
||||||
std::ostringstream out;
|
auto out = std::ostringstream{};
|
||||||
Main(in, out);
|
Main(in, out);
|
||||||
CHECK(out.str() == "Part 1: 1651\nPart 2: 1707\n");
|
CHECK(out.str() == "Part 1: 1651\nPart 2: 1707\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("shortest path") {
|
TEST_CASE("shortest path") {
|
||||||
distance_array<int> distances{boost::extents[4][4]};
|
auto distances = distance_array<int>{boost::extents[4][4]};
|
||||||
std::fill_n(distances.data(), distances.num_elements(), 100);
|
std::fill_n(distances.data(), distances.num_elements(), 100);
|
||||||
|
|
||||||
distances[0][2] = -2;
|
distances[0][2] = -2;
|
||||||
|
|
36
2022/18.cpp
36
2022/18.cpp
|
@ -4,6 +4,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stack>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -24,12 +25,14 @@ using Coord = aocpp::Vec<std::int64_t, 3>;
|
||||||
/// @return set of coordinates
|
/// @return set of coordinates
|
||||||
auto Parse(std::istream & in) -> std::set<Coord>
|
auto Parse(std::istream & in) -> std::set<Coord>
|
||||||
{
|
{
|
||||||
std::set<Coord> result;
|
auto result = std::set<Coord>{};
|
||||||
std::string line;
|
auto line = std::string{};
|
||||||
|
|
||||||
while (in >> line) {
|
while (in >> line) {
|
||||||
Coord x;
|
auto x = Coord{};
|
||||||
if (3 != std::sscanf(line.c_str(), "%lld,%lld,%lld\n", &x[0], &x[1], &x[2]))
|
if (3 != std::sscanf(line.c_str(), "%lld,%lld,%lld\n", &x[0], &x[1], &x[2])) {
|
||||||
throw std::runtime_error{"bad input line"};
|
throw std::runtime_error{"bad input line"};
|
||||||
|
}
|
||||||
result.insert(x);
|
result.insert(x);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -37,8 +40,8 @@ auto Parse(std::istream & in) -> std::set<Coord>
|
||||||
|
|
||||||
auto Part1(std::set<Coord> const& obj) -> std::size_t
|
auto Part1(std::set<Coord> const& obj) -> std::size_t
|
||||||
{
|
{
|
||||||
std::size_t result {0};
|
auto result = std::size_t{0};
|
||||||
for (auto && x : obj) {
|
for (auto const& x : obj) {
|
||||||
x.EachNeighbor([&](Coord const& y) {
|
x.EachNeighbor([&](Coord const& y) {
|
||||||
if (!obj.contains(y)) result++;
|
if (!obj.contains(y)) result++;
|
||||||
});
|
});
|
||||||
|
@ -49,21 +52,24 @@ auto Part1(std::set<Coord> const& obj) -> std::size_t
|
||||||
auto Part2(std::set<Coord> const& obj) -> std::size_t
|
auto Part2(std::set<Coord> const& obj) -> std::size_t
|
||||||
{
|
{
|
||||||
auto [lo, hi] = Coord::BoundingBox(obj.begin(), obj.end());
|
auto [lo, hi] = Coord::BoundingBox(obj.begin(), obj.end());
|
||||||
lo -= Coord(1);
|
lo -= Coord{1};
|
||||||
hi += Coord(1);
|
hi += Coord{1};
|
||||||
|
|
||||||
std::set<Coord> seen {lo};
|
auto seen = std::set<Coord>{};
|
||||||
std::vector<Coord> work {lo};
|
auto work = std::stack<Coord>{};
|
||||||
std::size_t result {0};
|
auto result = std::size_t{0};
|
||||||
|
|
||||||
|
work.push(lo);
|
||||||
|
seen.insert(lo);
|
||||||
|
|
||||||
while (!work.empty()) {
|
while (!work.empty()) {
|
||||||
auto x = work.back();
|
auto const x = work.top();
|
||||||
work.pop_back();
|
work.pop();
|
||||||
x.EachNeighbor([&, lo=lo, hi=hi](Coord const& y) {
|
x.EachNeighbor([&, lo=lo, hi=hi](Coord const& y) {
|
||||||
if (obj.contains(y)) {
|
if (obj.contains(y)) {
|
||||||
result++;
|
result++;
|
||||||
} else if (y.InRange(lo, hi) && seen.insert(y).second) {
|
} else if (y.InRange(lo, hi) && seen.insert(y).second) {
|
||||||
work.push_back(y);
|
work.push(y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -98,7 +104,7 @@ TEST_SUITE("2022-12 examples") {
|
||||||
|
|
||||||
auto Main(std::istream & in, std::ostream & out) -> void
|
auto Main(std::istream & in, std::ostream & out) -> void
|
||||||
{
|
{
|
||||||
auto const obj {Parse(in)};
|
auto const obj = Parse(in);
|
||||||
out << "Part 1: " << Part1(obj) << std::endl;
|
out << "Part 1: " << Part1(obj) << std::endl;
|
||||||
out << "Part 2: " << Part2(obj) << std::endl;
|
out << "Part 2: " << Part2(obj) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
25
2022/20.cpp
25
2022/20.cpp
|
@ -4,6 +4,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -24,7 +25,7 @@ using Input = std::vector<std::int64_t>;
|
||||||
/// @return outer list of elves, inner lists of calories
|
/// @return outer list of elves, inner lists of calories
|
||||||
auto Parse(std::istream & in) -> Input
|
auto Parse(std::istream & in) -> Input
|
||||||
{
|
{
|
||||||
Input result;
|
auto result = Input{};
|
||||||
using It = std::istream_iterator<std::int64_t>;
|
using It = std::istream_iterator<std::int64_t>;
|
||||||
std::copy<It>(in, {}, std::back_inserter(result));
|
std::copy<It>(in, {}, std::back_inserter(result));
|
||||||
return result;
|
return result;
|
||||||
|
@ -33,7 +34,17 @@ auto Parse(std::istream & in) -> Input
|
||||||
auto Solve(Input const& input, std::size_t const rounds) -> std::int64_t
|
auto Solve(Input const& input, std::size_t const rounds) -> std::int64_t
|
||||||
{
|
{
|
||||||
auto const len = input.size();
|
auto const len = input.size();
|
||||||
std::vector<std::size_t> fwds(len), bwds(len);
|
auto fwds = std::vector<std::size_t>(len);
|
||||||
|
auto bwds = std::vector<std::size_t>(len);
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
throw std::runtime_error{"Input too small"};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const zero_it = std::find(input.begin(), input.end(), 0);
|
||||||
|
if (zero_it == input.end()) {
|
||||||
|
throw std::runtime_error{"no zero element in input"};
|
||||||
|
}
|
||||||
|
|
||||||
std::iota(fwds.begin(), fwds.end()-1, 1); fwds.back() = 0;
|
std::iota(fwds.begin(), fwds.end()-1, 1); fwds.back() = 0;
|
||||||
std::iota(bwds.begin()+1, bwds.end(), 0); bwds.front() = len-1;
|
std::iota(bwds.begin()+1, bwds.end(), 0); bwds.front() = len-1;
|
||||||
|
@ -67,8 +78,8 @@ auto Solve(Input const& input, std::size_t const rounds) -> std::int64_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int64_t sum {0};
|
auto sum = std::int64_t{0};
|
||||||
auto cursor = std::distance(input.begin(), std::find(input.begin(), input.end(), 0));
|
auto cursor = std::distance(input.begin(), zero_it);
|
||||||
for (auto const _ : boost::irange(3)) {
|
for (auto const _ : boost::irange(3)) {
|
||||||
for (auto const _ : boost::irange(1000)) {
|
for (auto const _ : boost::irange(1000)) {
|
||||||
cursor = fwds[cursor];
|
cursor = fwds[cursor];
|
||||||
|
@ -86,7 +97,7 @@ auto Part1(Input const& input) -> std::int64_t
|
||||||
|
|
||||||
auto Part2(Input input) -> std::int64_t
|
auto Part2(Input input) -> std::int64_t
|
||||||
{
|
{
|
||||||
for (auto& x : input) { x *= 811589153; }
|
for (auto& x : input) { x *= 811'589'153; }
|
||||||
return Solve(input, 10);
|
return Solve(input, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,13 +115,13 @@ TEST_SUITE("2022-20 examples") {
|
||||||
"4\n"};
|
"4\n"};
|
||||||
auto input = Parse(in);
|
auto input = Parse(in);
|
||||||
CHECK(3 == Part1(input));
|
CHECK(3 == Part1(input));
|
||||||
CHECK(1623178306 == Part2(input));
|
CHECK(1623178306 == Part2(std::move(input)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Main(std::istream & in, std::ostream & out) -> void
|
auto Main(std::istream & in, std::ostream & out) -> void
|
||||||
{
|
{
|
||||||
auto input {Parse(in)};
|
auto input = Parse(in);
|
||||||
out << "Part 1: " << Part1(input) << std::endl;
|
out << "Part 1: " << Part1(input) << std::endl;
|
||||||
out << "Part 2: " << Part2(std::move(input)) << std::endl;
|
out << "Part 2: " << Part2(std::move(input)) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user