3
This commit is contained in:
parent
1b5607c8fe
commit
5de6db8780
@ -23,6 +23,9 @@ target_link_libraries(day01 aocpp)
|
||||
add_executable(day02 day02.cpp)
|
||||
target_link_libraries(day02 aocpp intcode)
|
||||
|
||||
add_executable(day03 day03.cpp)
|
||||
target_link_libraries(day03 aocpp)
|
||||
|
||||
add_executable(day05 day05.cpp)
|
||||
target_link_libraries(day05 aocpp intcode)
|
||||
|
||||
|
93
day03.cpp
Normal file
93
day03.cpp
Normal 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 fin = aocpp::Startup(argc, argv);
|
||||
|
||||
std::string line;
|
||||
std::getline(fin, line);
|
||||
auto wire0 = BuildLine(line);
|
||||
std::getline(fin, 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;
|
||||
}
|
17
day23.cpp
17
day23.cpp
@ -1,3 +1,4 @@
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
@ -15,16 +16,14 @@ 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) -> std::vector<Machine> {
|
||||
std::vector<Machine> machines;
|
||||
machines.reserve(50);
|
||||
|
||||
auto BuildNetwork(Machine m) -> Machines {
|
||||
Machines machines;
|
||||
auto& i = std::get<Input>(Step(m)).input;
|
||||
for (i = 0; i < 50; i++) {
|
||||
machines.push_back(m);
|
||||
for (i = 0; i < machines.size(); i++) {
|
||||
machines[i] = m;
|
||||
}
|
||||
|
||||
return machines;
|
||||
}
|
||||
|
||||
@ -56,7 +55,7 @@ auto Interact(Ethernet & ethernet, Machine & m, std::optional<Payload> p) -> voi
|
||||
|
||||
} // namespace
|
||||
|
||||
auto main(int argc, char** argv) -> int {
|
||||
auto main(int const argc, char** const argv) -> int {
|
||||
auto fin = aocpp::Startup(argc, argv);
|
||||
auto machines = BuildNetwork(Machine{ParseStream(fin)});
|
||||
auto ethernet = Ethernet{};
|
||||
@ -67,7 +66,7 @@ auto main(int argc, char** argv) -> int {
|
||||
|
||||
for(;;) {
|
||||
if (!ethernet.empty()) {
|
||||
auto packet = ethernet.front();
|
||||
auto const packet = ethernet.front();
|
||||
ethernet.pop_front();
|
||||
if (packet.destination == 255) {
|
||||
nat = packet.payload;
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace intcode {
|
||||
|
||||
BadInstruction::BadInstruction(char const* what)
|
||||
BadInstruction::BadInstruction(char const* const what)
|
||||
: std::runtime_error{what} {}
|
||||
|
||||
auto StepInput(Machine & m, ValueType input) -> void {
|
||||
auto StepInput(Machine & m, ValueType const input) -> void {
|
||||
std::get<Input>(Step(m)).input = input;
|
||||
}
|
||||
|
||||
@ -15,67 +15,58 @@ auto StepOutput(Machine & m) -> ValueType {
|
||||
|
||||
auto Step(Machine & m) -> std::variant<Input, Output, Halt> {
|
||||
for (;;) {
|
||||
auto instruction = m.Next();
|
||||
auto modes = instruction / 10;
|
||||
auto next = m.Next();
|
||||
auto const instruction = next % 100; next /= 100;
|
||||
|
||||
auto arg = [&]() -> ValueType & {
|
||||
auto const arg = [&]() -> ValueType & {
|
||||
auto &v = m.Next();
|
||||
switch ((modes /= 10) % 10) {
|
||||
case 0:
|
||||
return m.At(v);
|
||||
case 1:
|
||||
return v;
|
||||
case 2:
|
||||
return m.Rel(v);
|
||||
default:
|
||||
throw BadInstruction{"invalid addressing mode"};
|
||||
auto const mode = next % 10; next /= 10;
|
||||
switch (mode) {
|
||||
case 0: return m.At(v);
|
||||
case 1: return v;
|
||||
case 2: return m.Rel(v);
|
||||
default: throw BadInstruction{"invalid addressing mode"};
|
||||
}
|
||||
};
|
||||
|
||||
switch (instruction % 100) {
|
||||
case 1: {
|
||||
switch (instruction) {
|
||||
case 1:
|
||||
arg() = arg() + arg();
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
case 2:
|
||||
arg() = arg() * arg();
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
case 3:
|
||||
return Input{arg()};
|
||||
}
|
||||
|
||||
case 4: {
|
||||
case 4:
|
||||
return Output{arg()};
|
||||
}
|
||||
|
||||
case 5: {
|
||||
auto a = arg();
|
||||
auto b = arg();
|
||||
auto const a = arg();
|
||||
auto const b = arg();
|
||||
if (a) { m.Goto(b); }
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
auto a = arg();
|
||||
auto b = arg();
|
||||
auto const a = arg();
|
||||
auto const b = arg();
|
||||
if (!a) { m.Goto(b); }
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: {
|
||||
auto a = arg();
|
||||
auto b = arg();
|
||||
arg() = a < b; // order matters
|
||||
auto const a = arg();
|
||||
arg() = a < arg();
|
||||
break;
|
||||
}
|
||||
|
||||
case 8: {
|
||||
case 8:
|
||||
arg() = arg() == arg();
|
||||
break;
|
||||
}
|
||||
|
||||
case 9:
|
||||
m.Rebase(arg());
|
||||
@ -85,6 +76,7 @@ auto Step(Machine & m) -> std::variant<Input, Output, Halt> {
|
||||
return Halt{};
|
||||
|
||||
default:
|
||||
std::cout << instruction << std::endl;
|
||||
throw BadInstruction{"invalid opcode"};
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,17 @@ namespace intcode {
|
||||
Machine::Machine() : rom_{}, ram_{}, pc_{0}, base_{0} {}
|
||||
|
||||
Machine::Machine(std::vector<ValueType> program)
|
||||
: rom_{program}, ram_{}, pc_{0}, base_{0} {}
|
||||
: rom_{std::move(program)}, ram_{}, pc_{0}, base_{0} {}
|
||||
|
||||
auto Machine::At(std::size_t i) -> ValueType & {
|
||||
auto Machine::At(std::size_t const i) -> ValueType & {
|
||||
return i < rom_.size() ? rom_[i] : ram_[i];
|
||||
}
|
||||
|
||||
auto Machine::Rel(std::size_t i) -> ValueType & {
|
||||
auto Machine::Rel(std::size_t const i) -> ValueType & {
|
||||
return At(base_ + i);
|
||||
}
|
||||
|
||||
auto Machine::Rebase(std::size_t offset) -> void {
|
||||
auto Machine::Rebase(std::size_t const offset) -> void {
|
||||
base_ += offset;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ auto Machine::Next() -> ValueType & {
|
||||
return At(pc_++);
|
||||
}
|
||||
|
||||
auto Machine::Goto(std::size_t address) -> void {
|
||||
auto Machine::Goto(std::size_t const address) -> void {
|
||||
pc_ = address;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,8 @@ auto CW(Coord) -> Coord;
|
||||
/// Rotate counter-clockwise
|
||||
auto CCW(Coord) -> Coord;
|
||||
|
||||
auto Norm1(Coord) -> std::int64_t;
|
||||
|
||||
/// Add two coordinates pairwise
|
||||
auto operator+(Coord, Coord) -> Coord;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <aocpp/Coord.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace aocpp {
|
||||
|
||||
auto Draw(std::ostream & out, std::map<Coord, std::int64_t> image) -> void {
|
||||
@ -65,6 +67,10 @@ auto CCW(Coord c) -> Coord {
|
||||
return c;
|
||||
}
|
||||
|
||||
auto Norm1(Coord c) -> std::int64_t {
|
||||
return std::abs(c.x) + std::abs(c.y);
|
||||
}
|
||||
|
||||
auto operator+(Coord a, Coord b) -> Coord {
|
||||
return {a.x + b.x, a.y + b.y};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user