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