diff options
author | kaiwu <kaiwu2004@gmail.com> | 2022-05-10 09:43:50 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2022-05-10 09:43:50 +0800 |
commit | e9c464934c764ef7971684e1785587fd18dca81d (patch) | |
tree | 366446140395abdf091d0ef40cc0f009f66abf49 | |
parent | 2e5392ba4c93d5b9d5eb2a560418b13e76f2059f (diff) | |
download | advent-of-code-e9c464934c764ef7971684e1785587fd18dca81d.tar.gz advent-of-code-e9c464934c764ef7971684e1785587fd18dca81d.zip |
2017 day8
-rw-r--r-- | src/2017/day8/README.md | 3 | ||||
-rw-r--r-- | src/2017/day8/aoc.cpp | 85 | ||||
-rw-r--r-- | src/2017/day8/aoc.h | 1 | ||||
-rw-r--r-- | test/test_2017.cpp | 7 |
4 files changed, 95 insertions, 1 deletions
diff --git a/src/2017/day8/README.md b/src/2017/day8/README.md index 625d634..efa3bbd 100644 --- a/src/2017/day8/README.md +++ b/src/2017/day8/README.md @@ -22,4 +22,5 @@ You might also encounter <= (less than or equal to) or != (not equal to). Howeve What is the largest value in any register after completing the instructions in your puzzle input? - +--- Part Two --- +To be safe, the CPU also needs to know the highest value held in any register during this process so that it can decide how much memory to allocate to these operations. For example, in the above instructions, the highest value ever held was 10 (in register c after the third instruction was evaluated). diff --git a/src/2017/day8/aoc.cpp b/src/2017/day8/aoc.cpp index ed2d9d3..a5af770 100644 --- a/src/2017/day8/aoc.cpp +++ b/src/2017/day8/aoc.cpp @@ -1,5 +1,90 @@ #include "aoc.h" +#include <unordered_map> namespace aoc2017 { +int largest(const std::unordered_map<line_view, int>& rs) { + int max{INT32_MIN}; + for (auto& kv : rs) { + if (kv.second > max) { + max = kv.second; + } + } + return max; } + +static void get_number(const char** pp, int* d) { + const char* p = *pp; + *d = 0; + int sign = 1; + if (*p == '-') { + sign = -1; + p++; + } + while (*p >= '0' && *p <= '9') { + *d = *d * 10 + *p - '0'; + p++; + } + *d = *d * sign; + *pp = p; +} + +line_view get_label(const char** pp) { + const char* p = *pp; + const char* p1 = p; + while (*p != ' ') { + p++; + } + *pp = p; + return {p1, p}; +} + +static int inc(int x, int i) { return x + i; } +static int dec(int x, int i) { return x - i; } +static bool condition_met(line_view cond, int x, int i) { + if (cond.length > 1) { + if (*cond.line == '!') { + return x != i; + } + if (*cond.line == '=') { + return x == i; + } + return (*cond.line == '>') ? x >= i : x <= i; + } + return (*cond.line == '>') ? x > i : x < i; +} + +typedef int (*op)(int, int); +std::pair<int, int> day8(line_view file) { + std::unordered_map<line_view, int> registers; + int max{INT32_MIN}; + per_line(file, [®isters, &max](line_view lv) { + const char* p = lv.line; + line_view v1 = get_label(&p); + op f = p[1] == 'd' ? dec : inc; + + p += 5; + int d1{0}; + get_number(&p, &d1); + + p += 4; + line_view v2 = get_label(&p); + + p += 1; + line_view condition = get_label(&p); + + p += 1; + int d2{0}; + get_number(&p, &d2); + if (condition_met(condition, registers[v2], d2)) { + registers[v1] = f(registers[v1], d1); + if (registers[v1] > max) { + max = registers[v1]; + } + } + return true; + }); + return {largest(registers), max}; +} + +} // namespace aoc2017 diff --git a/src/2017/day8/aoc.h b/src/2017/day8/aoc.h index 7aacc4c..0fd1440 100644 --- a/src/2017/day8/aoc.h +++ b/src/2017/day8/aoc.h @@ -3,4 +3,5 @@ namespace aoc2017 { +std::pair<int, int> day8(line_view); } diff --git a/test/test_2017.cpp b/test/test_2017.cpp index 572072f..8fd47fe 100644 --- a/test/test_2017.cpp +++ b/test/test_2017.cpp @@ -70,3 +70,10 @@ TEST_CASE("Recursive Circus", "[2017]") { // REQUIRE(strcmp(x, "tknk") == 0); REQUIRE(strcmp(x, "svugo") == 0); } + +TEST_CASE("I Heard You Like Registers", "[2017]") { + line_view lv = load_file("../src/2017/day8/input"); + auto p = aoc2017::day8(lv); + REQUIRE(4567 == p.first); + REQUIRE(5636 == p.second); +} |