mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement day 05.
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
#include <iostream>
|
||||
#include "days.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
void aoc2019::day05_part1(std::istream &input, std::ostream &output) {
|
||||
output << "Not implemented\n";
|
||||
auto program = read_intcode(input);
|
||||
auto result = aoc2019::run_intcode(program, { 1 });
|
||||
output << result.back() << std::endl;
|
||||
}
|
||||
|
||||
void aoc2019::day05_part2(std::istream &input, std::ostream &output) {
|
||||
output << "Not implemented\n";
|
||||
auto program = read_intcode(input);
|
||||
auto result = run_intcode(program, { 5 });
|
||||
output << result.back() << std::endl;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <iostream>
|
||||
#include "utils.hpp"
|
||||
|
||||
std::string_view aoc2019::strtok(std::string_view &str, char token) {
|
||||
@@ -10,3 +11,105 @@ std::string_view aoc2019::strtok(std::string_view &str, char token) {
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
std::vector<int> aoc2019::run_intcode(std::vector<int> &program, std::deque<int> inputs) {
|
||||
std::vector<int> outputs{};
|
||||
int ip = 0;
|
||||
auto interpret_value = [&program, &ip](int pos) {
|
||||
bool immediate = false;
|
||||
switch (pos) {
|
||||
case 1:
|
||||
immediate = program[ip] / 100 % 10;
|
||||
break;
|
||||
case 2:
|
||||
immediate = program[ip] / 1000 % 10;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
immediate = program[ip] / 10000 % 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::out_of_range("Invalid position");
|
||||
}
|
||||
|
||||
if (immediate) {
|
||||
return program[ip + pos];
|
||||
} else {
|
||||
return program[program[ip + pos]];
|
||||
}
|
||||
};
|
||||
|
||||
while (ip < program.size()) {
|
||||
switch (program[ip] % 100) {
|
||||
case 1:
|
||||
program[program[ip + 3]] = interpret_value(1) + interpret_value(2);
|
||||
ip += 4;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
program[program[ip + 3]] = interpret_value(1) * interpret_value(2);
|
||||
ip += 4;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (inputs.empty()) {
|
||||
throw std::out_of_range("No inputs left");
|
||||
}
|
||||
program[program[ip + 1]] = inputs.front();
|
||||
inputs.pop_front();
|
||||
ip += 2;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
outputs.push_back(interpret_value(1));
|
||||
ip += 2;
|
||||
break;
|
||||
|
||||
case 5: // Jump if non-zero
|
||||
if (interpret_value(1)) {
|
||||
ip = interpret_value(2);
|
||||
} else {
|
||||
ip += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: // Jump if zero
|
||||
if (!interpret_value(1)) {
|
||||
ip = interpret_value(2);
|
||||
} else {
|
||||
ip += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: // equality
|
||||
program[program[ip + 3]] = interpret_value(1) < interpret_value(2);
|
||||
ip += 4;
|
||||
break;
|
||||
|
||||
case 8: // less than
|
||||
program[program[ip + 3]] = interpret_value(1) == interpret_value(2) ? 1 : 0;
|
||||
ip += 4;
|
||||
break;
|
||||
|
||||
case 99:
|
||||
return outputs;
|
||||
|
||||
default:
|
||||
char buffer[30];
|
||||
std::snprintf(buffer, sizeof(buffer), "Invalid opcode: %d", program[ip]);
|
||||
|
||||
throw std::domain_error(buffer);
|
||||
}
|
||||
}
|
||||
throw std::out_of_range("Program read out of bounds");
|
||||
}
|
||||
|
||||
std::vector<int> aoc2019::read_intcode(std::istream &input) {
|
||||
std::vector<int> program{};
|
||||
for (int current; input >> current; input.ignore()) {
|
||||
program.push_back(current);
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <charconv>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace aoc2019 {
|
||||
|
||||
template<typename T>
|
||||
inline std::from_chars_result from_chars(std::string_view str, T& value) {
|
||||
inline std::from_chars_result from_chars(std::string_view str, T &value) {
|
||||
return std::from_chars(str.data(), str.data() + str.size(), value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void combine_hash(std::size_t& seed, const T& o) {
|
||||
void combine_hash(std::size_t &seed, const T &o) {
|
||||
// Algorithm taken from boost::combine_hash.
|
||||
std::hash<T> hash{};
|
||||
seed ^= hash(o) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
std::string_view strtok(std::string_view &str, char token = ',');
|
||||
|
||||
std::vector<int> read_intcode(std::istream &input);
|
||||
|
||||
std::vector<int> run_intcode(std::vector<int> &program, std::deque<int> inputs = {});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user