generalize to a repo for all years

This commit is contained in:
Eric Mertens
2022-11-08 09:13:11 -08:00
parent 025363cc0c
commit 177e38cd14
15 changed files with 39 additions and 39 deletions

26
2019/01.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <aocpp/Startup.hpp>
auto main(int argc, char** argv) -> int {
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 (in >> x) {
part1 += fuel(x);
for (; x > 0; fuel(x)) {
part2 += x;
}
}
std::cout << "Part 1: " << part1 << std::endl;
std::cout << "Part 2: " << part2 << std::endl;
}

32
2019/02.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include <iostream>
#include <utility>
#include <aocpp/Startup.hpp>
#include <intcode/intcode.hpp>
using namespace intcode;
namespace {
auto Compute(Machine machine, ValueType x, ValueType y) {
machine.At(1) = x;
machine.At(2) = y;
Step(machine);
return machine.At(0);
}
} // namespace
auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Compute(machine, 12, 2) << std::endl;
for (std::int64_t i = 0; i < 100; i++) {
for (std::int64_t j = 0; j < 100; j++) {
if (19690720 == Compute(machine, i, j)) {
std::cout << "Part 2: " << 100 * i + j << std::endl;
}
}
}
}

93
2019/03.cpp Normal file
View File

@@ -0,0 +1,93 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <map>
#include <tuple>
#include <string>
#include <aocpp/Coord.hpp>
#include <aocpp/Startup.hpp>
using namespace aocpp;
namespace {
auto BuildLine(std::string instructions) -> std::vector<Coord>
{
Coord here {};
std::vector<Coord> wire;
auto it = std::begin(instructions);
auto end = std::end(instructions);
while (it != end) {
auto start = it;
it = std::find(it, end, ',');
if (start == it) { throw std::runtime_error{"null command"}; }
Coord (*step)(Coord);
switch (*start++) {
case 'U': step = Up; break;
case 'D': step = Down; break;
case 'L': step = Left; break;
case 'R': step = Right; break;
default: throw std::runtime_error{"bad command letter"};
}
auto n = std::stol(std::string{start, it});
for (int i = 0; i < n; i++) {
here = step(here);
wire.push_back(here);
}
// skip over comma
if (it != end) it++;
}
return wire;
}
struct Entry { bool w0, w1; std::int64_t part2; };
auto Record (
std::map<Coord, Entry> & m,
bool Entry::* which,
std::vector<Coord> const& wire
) -> void {
for (std::size_t i = 0; i < wire.size(); i++) {
auto & entry = m[wire[i]];
if (!(entry.*which)) {
entry.*which = true;
entry.part2 += i+1;
}
}
}
} // namespace
auto main(int argc, char** argv) -> int {
auto& in = aocpp::Startup(argc, argv);
std::string line;
std::getline(in, line);
auto wire0 = BuildLine(line);
std::getline(in, line);
auto wire1 = BuildLine(line);
std::map<Coord, Entry> counts;
Record(counts, &Entry::w0, wire0);
Record(counts, &Entry::w1, wire1);
std::int64_t part1 = std::numeric_limits<std::int64_t>::max();
std::int64_t part2 = std::numeric_limits<std::int64_t>::max();
for (auto & [k,v] : counts) {
if (v.w0 && v.w1) {
part1 = std::min(part1, Norm1(k));
part2 = std::min(part2, v.part2);
}
}
std::cout << "Part 1: " << part1 << std::endl;
std::cout << "Part 2: " << part2 << std::endl;
}

62
2019/04.cpp Normal file
View File

@@ -0,0 +1,62 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <tuple>
#include <fstream>
#include <iterator>
#include <vector>
#include <aocpp/Startup.hpp>
namespace {
auto Parse(std::istream & in) -> std::pair<std::int64_t, std::int64_t> {
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;
}

24
2019/05.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include <iostream>
#include <utility>
#include <aocpp/Startup.hpp>
#include <intcode/intcode.hpp>
using namespace intcode;
namespace {
auto Compute(Machine machine, ValueType d) -> ValueType {
ValueType last_output = -1;
Run(machine,
[=]() { return d; },
[&](auto o) { last_output = o; });
return last_output;
}
} // namespace
auto main(int argc, char** argv) -> int {
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;
}

81
2019/06.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <map>
#include <aocpp/Startup.hpp>
namespace {
auto Parse(std::istream & in) {
std::map<std::string, std::string> 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<std::string, std::string> const& parents, std::string const& start)
{
std::vector<std::string> path;
std::string const* name = &start;
while (*name != "COM") {
name = &parents.at(*name);
path.push_back(*name);
}
return path;
}
auto Part1(std::map<std::string, std::string> const& parents) {
std::map<std::string, std::size_t> depths {{"COM", 0}};
std::size_t part1 {0};
for (auto & [k, _] : parents) {
std::string const* cursor = &k;
std::vector<std::string const*> 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<std::string, std::string> 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;
}

68
2019/07.cpp Normal file
View File

@@ -0,0 +1,68 @@
#include <algorithm>
#include <concepts>
#include <iostream>
#include <optional>
#include <utility>
#include <vector>
#include <aocpp/Startup.hpp>
#include <intcode/intcode.hpp>
using namespace intcode;
namespace {
template <class R> auto Controller(Machine machine, R const &params) {
auto& i = std::get<Input>(Step(machine)).input;
std::vector<Machine> amps;
amps.reserve(params.size());
for (auto p : params) {
i = p;
amps.push_back(machine);
}
return amps;
}
template <class R>
auto Feed(R &&amps, ValueType start) -> std::optional<ValueType> {
for (auto &m : amps) {
auto e = Step(m);
if (auto i = std::get_if<Input>(&e)) {
i->input = start;
start = StepOutput(m);
} else {
return {};
}
}
return {start};
}
auto compute1(Machine machine, std::vector<ValueType> const &params)
-> ValueType {
return *Feed(Controller(std::move(machine), params), 0);
}
auto compute2(Machine machine, std::vector<ValueType> const &params)
-> ValueType {
auto amps = Controller(std::move(machine), params);
ValueType last = 0;
while (auto next = Feed(amps, last)) {
last = *next;
}
return last;
}
template <std::invocable<Machine, std::vector<ValueType> const &> F>
auto optimize(Machine machine, std::vector<ValueType> params, F f) {
ValueType best = 0;
do {
best = std::max(best, f(machine, params));
} while (std::next_permutation(params.begin(), params.end()));
return best;
}
} // namespace
auto main(int argc, char** argv) -> int {
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;
}

74
2019/08.cpp Normal file
View File

@@ -0,0 +1,74 @@
#include <algorithm>
#include <cstdint>
#include <array>
#include <iostream>
#include <iterator>
#include <vector>
#include <aocpp/Startup.hpp>
namespace {
using Layer = std::array<char, 150>;
auto SplitLayers(std::istream & in) {
std::string line;
std::getline(in, line);
std::vector<Layer> layers;
auto it = line.begin();
auto layer_n = line.size() / 150;
for (std::size_t layer = 0; layer < layer_n; layer++) {
layers.push_back({});
for (std::size_t y = 0; y < 150; y++) {
layers.back()[y] = *it++;
}
}
return layers;
}
auto Part1(std::vector<Layer> const& layers) {
std::size_t part1 = 0;
std::size_t seen = std::numeric_limits<std::size_t>::max();
for (auto & layer : layers) {
auto zeros = std::count(layer.begin(), layer.end(), '0');
if (zeros < seen) {
seen = zeros;
part1
= std::count(layer.begin(), layer.end(), '1')
* std::count(layer.begin(), layer.end(), '2');
}
}
return part1;
}
auto Flatten(std::vector<Layer> const& layers) {
Layer merged {};
for (std::size_t i = 0; i < 150; i++) {
for (auto & layer : layers) {
if ('2' != layer[i]) {
merged[i] = layer[i];
break;
}
}
}
return merged;
}
auto Draw(Layer picture) {
for (std::size_t y = 0; y < 6; y++) {
for (std::size_t x = 0; x < 25; x++) {
std::cout << ('1' == picture[y*25+x] ? "" : "");
}
std::cout << std::endl;
}
}
} // namespace
auto main(int argc, char** argv) -> int {
auto layers = SplitLayers(aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Part1(layers) << std::endl;
Draw(Flatten(layers));
}

24
2019/09.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include <iostream>
#include <utility>
#include <aocpp/Startup.hpp>
#include <intcode/intcode.hpp>
using namespace intcode;
namespace {
auto Compute(Machine machine, ValueType d) -> ValueType {
ValueType output = -1;
Run(machine,
[=](){ return d; },
[&](auto o) { output = o; });
return output;
}
} // namespace
auto main(int argc, char** argv) -> int {
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;
}

44
2019/11.cpp Normal file
View File

@@ -0,0 +1,44 @@
#include <iostream>
#include <utility>
#include <tuple>
#include <map>
#include <aocpp/Startup.hpp>
#include <aocpp/Coord.hpp>
#include <intcode/intcode.hpp>
using namespace aocpp;
using namespace intcode;
namespace {
auto Compute(Machine machine, ValueType start)
-> std::map<Coord, ValueType> {
Coord here {0,0};
std::map<Coord, ValueType> paint {{here,start}};
Coord dir {0, -1};
bool next_color = true;
Run(machine,
[&]() { return paint[here]; },
[&](auto o) {
if (next_color) {
paint[here] = o;
} else {
dir = (o ? CW : CCW)(dir);
here += dir;
}
next_color = !next_color;
});
return paint;
}
} // namespace
auto main(int argc, char** argv) -> int {
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));
}

66
2019/13.cpp Normal file
View File

@@ -0,0 +1,66 @@
#include <iostream>
#include <stdexcept>
#include <utility>
#include <tuple>
#include <set>
#include <aocpp/Startup.hpp>
#include <aocpp/Coord.hpp>
#include <intcode/intcode.hpp>
using namespace aocpp;
using namespace intcode;
namespace {
auto Compute1(Machine machine)
-> std::size_t {
std::set<Coord> screen;
Run(machine,
[]() -> ValueType { throw std::runtime_error{"unexpected input request"}; },
[&](auto x) {
auto y = StepOutput(machine);
auto v = StepOutput(machine);
if (2 == v) { screen.insert({x,y}); } else { screen.erase({x,y}); }
});
return screen.size();
}
auto Compute2(Machine machine) {
ValueType score {0};
ValueType paddleX {0};
ValueType ballX {0};
machine.At(0) = 2;
Run(machine,
[&]() {
return paddleX < ballX ? 1 : paddleX > ballX ? -1 : 0;
},
[&](auto x) {
auto y = StepOutput(machine);
auto v = StepOutput(machine);
if (-1 == x && 0 == y) {
score = v;
} else {
switch (v) {
case 3: // paddle
paddleX = x;
break;
case 4: // ball
ballX = x;
break;
}
}
});
return score;
}
} // namespace
auto main(int argc, char** argv) -> int {
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;
}

97
2019/15.cpp Normal file
View File

@@ -0,0 +1,97 @@
#include <algorithm>
#include <deque>
#include <iostream>
#include <map>
#include <tuple>
#include <utility>
#include <vector>
#include <aocpp/Coord.hpp>
#include <aocpp/Startup.hpp>
#include <intcode/intcode.hpp>
using namespace aocpp;
using namespace intcode;
namespace {
using CoordOp = Coord(Coord);
CoordOp* const moves[4] {Up, Down, Left, Right};
auto Interact(Machine & m, ValueType cmd) -> ValueType {
StepInput(m, cmd);
return StepOutput(m);
}
auto CounterCommand(ValueType x) -> ValueType {
return ((x-1)^1)+1;
}
// Depth first search of the maze
auto Explore(Machine m) -> std::map<Coord, ValueType> {
std::map<Coord, ValueType> world;
std::vector<ValueType> path {0};
Coord here {};
for(;;) {
while (path.back() < 4) {
path.back()++;
auto here_ = moves[path.back() - 1](here);
auto [it, success] = world.insert({here_,0});
if (success && 0 != (it->second = Interact(m, path.back()))) {
here = here_;
path.push_back(0);
}
}
path.pop_back();
if (path.empty()) { break; }
auto rev = CounterCommand(path.back());
here = moves[rev - 1](here);
Interact(m, rev);
}
return world;
}
// Breadth first search of maze finding shortest path to origin
// and furthest point in the maze from the airsource.
auto Compute(std::map<Coord, ValueType> world) -> std::pair<int, int> {
// Find starting coordinate and remove all the walls from the map
Coord start {};
for (auto it = world.begin(); it != world.end(); ) {
switch (it->second) {
case 2: start = it->first;
case 0: it = world.erase(it); break;
default: it++;
}
}
int part1 = -1;
int part2 = -1;
for (std::deque<std::pair<int, Coord>> todo {{0,start}};
!todo.empty();
todo.pop_front())
{
auto [steps, here] = todo.front();
if (Coord{0,0} == here) part1 = steps;
part2 = steps;
for (auto fn : moves) {
auto next = fn(here);
if (world.erase(next)) {
todo.emplace_back(steps+1, next);
}
}
}
return {part1, part2};
}
} // namespace
auto main(int argc, char** argv) -> int {
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;
}

89
2019/23.cpp Normal file
View File

@@ -0,0 +1,89 @@
#include <array>
#include <cstddef>
#include <deque>
#include <iostream>
#include <stdexcept>
#include <utility>
#include <variant>
#include <vector>
#include <aocpp/Startup.hpp>
#include <intcode/intcode.hpp>
using namespace intcode;
namespace {
struct Payload { ValueType x, y; };
struct Packet { ValueType destination; Payload payload; };
using Ethernet = std::deque<Packet>;
using Machines = std::array<Machine, 50>;
auto BuildNetwork(Machine m) -> Machines {
Machines machines;
auto& i = std::get<Input>(Step(m)).input;
for (i = 0; i < machines.size(); i++) {
machines[i] = m;
}
return machines;
}
auto Interact(Ethernet & ethernet, Machine & m, std::optional<Payload> p) -> void {
for(;;) {
auto e = Step(m);
switch (e.index()) {
default: throw std::runtime_error{"unexpected halt"};
case 0: {
auto& i = std::get<0>(e).input;
if (p) {
i = p->x;
StepInput(m, p->y);
p = {};
break;
}
i = -1; // no packet
return;
}
case 1: {
auto d = std::get<1>(e).output;
auto x = StepOutput(m);
auto y = StepOutput(m);
ethernet.push_back({d, {x,y}});
}
}
}
}
} // namespace
auto main(int const argc, char** const argv) -> int {
auto machines = BuildNetwork(Machine{ParseStream(aocpp::Startup(argc, argv))});
auto ethernet = Ethernet{};
std::optional<ValueType> part1;
std::optional<ValueType> part2;
std::optional<Payload> nat;
for(;;) {
if (!ethernet.empty()) {
auto const packet = ethernet.front();
ethernet.pop_front();
if (packet.destination == 255) {
nat = packet.payload;
if (!part1) { part1 = packet.payload.y; }
} else {
Interact(ethernet, machines.at(packet.destination), packet.payload);
}
} else if (nat) {
if (part2 == nat->y) { break; }
part2 = nat->y;
Interact(ethernet, machines[0], nat);
} else {
for (auto & m : machines) {
Interact(ethernet, m, {});
}
}
}
std::cout << "Part 1: " << *part1 << std::endl;
std::cout << "Part 2: " << *part2 << std::endl;
}

38
2019/CMakeLists.txt Normal file
View File

@@ -0,0 +1,38 @@
add_executable(01 01.cpp)
target_link_libraries(01 aocpp)
add_executable(02 02.cpp)
target_link_libraries(02 aocpp intcode)
add_executable(03 03.cpp)
target_link_libraries(03 aocpp)
add_executable(04 04.cpp)
target_link_libraries(04 aocpp)
add_executable(05 05.cpp)
target_link_libraries(05 aocpp intcode)
add_executable(06 06.cpp)
target_link_libraries(06 aocpp)
add_executable(07 07.cpp)
target_link_libraries(07 aocpp intcode)
add_executable(08 08.cpp)
target_link_libraries(08 aocpp)
add_executable(09 09.cpp)
target_link_libraries(09 aocpp intcode)
add_executable(11 11.cpp)
target_link_libraries(11 aocpp intcode)
add_executable(13 13.cpp)
target_link_libraries(13 aocpp intcode)
add_executable(15 15.cpp)
target_link_libraries(15 aocpp intcode)
add_executable(23 23.cpp)
target_link_libraries(23 aocpp intcode)