Made day 5 part 2 O(n) instead of O(n^2)

This commit is contained in:
Gnarwhal 2020-12-11 00:52:18 -08:00
parent 8c7cdc9aa2
commit b48ce8cb49
Signed by: Gnarwhal
GPG key ID: 0989A73D8C421174

View file

@ -32,7 +32,7 @@
#include "types.hpp" #include "types.hpp"
enum OpCode { Acc, Jmp, Nop }; enum OpCode { Acc, Jmp, Nop };
struct Op{ OpCode code; i32 num; }; struct Op{ OpCode code; i32 num; bool executed; };
auto extract_op(const std::string & string) -> Op { auto extract_op(const std::string & string) -> Op {
auto op = Op{ Nop, 0 }; auto op = Op{ Nop, 0 };
auto op_code_str = string.substr(0, 3); auto op_code_str = string.substr(0, 3);
@ -47,11 +47,11 @@ auto extract_op(const std::string & string) -> Op {
struct State{ u32 isp; i32 acc; }; struct State{ u32 isp; i32 acc; };
auto execute(State & state, const std::vector<Op> & ops) -> void { auto execute(State & state, std::vector<Op> & ops) -> void {
switch (ops[state.isp].code) { switch (ops[state.isp].code) {
case Acc: state.acc += ops[state.isp].num; ++state.isp; break; case Acc: ops[state.isp].executed = true; state.acc += ops[state.isp].num; ++state.isp; break;
case Jmp: state.isp += ops[state.isp].num; break; case Jmp: ops[state.isp].executed = true; state.isp += ops[state.isp].num; break;
case Nop: ++state.isp; break; case Nop: ops[state.isp].executed = true; ++state.isp; break;
} }
} }
@ -65,9 +65,8 @@ auto attempt_swap(State & state, std::vector<Op> & ops) -> bool {
} }
auto local_state = state; auto local_state = state;
auto executed = std::vector<bool>(ops.size()); ops[state.isp].executed = false;
while (local_state.isp < ops.size() && !executed[local_state.isp]) { while (local_state.isp < ops.size() && !ops[local_state.isp].executed) {
executed[local_state.isp] = true;
execute(local_state, ops); execute(local_state, ops);
} }
if (local_state.isp >= ops.size()) { if (local_state.isp >= ops.size()) {
@ -93,15 +92,15 @@ auto main(i32 argc, char * argv[]) -> i32 {
} }
auto state = State{ 0, 0 }; auto state = State{ 0, 0 };
auto executed = std::vector<bool>(ops.size()); while (!ops[state.isp].executed) {
while (!executed[state.isp]) {
executed[state.isp] = true;
execute(state, ops); execute(state, ops);
} }
std::cout << state.acc << std::endl; std::cout << state.acc << std::endl;
for (auto & op : ops) { op.executed = false; }
state = State{ 0, 0 }; state = State{ 0, 0 };
while (state.isp < ops.size()) { for (;;) {
if (attempt_swap(state, ops)) { if (attempt_swap(state, ops)) {
std::cout << state.acc << std::endl; std::cout << state.acc << std::endl;
break; break;