diff options
author | kaiwu <kaiwu2004@gmail.com> | 2022-04-06 16:25:14 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2022-04-06 16:25:14 +0800 |
commit | 844da9170858556950aa54d4843de332734e228f (patch) | |
tree | 8dfbcd140a0c3e7abe9064a68905b6f94a51a2b7 /src | |
parent | 749020a0961903ee89db0324d37c6132b4b061dc (diff) | |
download | advent-of-code-844da9170858556950aa54d4843de332734e228f.tar.gz advent-of-code-844da9170858556950aa54d4843de332734e228f.zip |
2017 day3
Diffstat (limited to 'src')
-rw-r--r-- | src/2017/day3/aoc.cpp | 5 | ||||
-rw-r--r-- | src/2017/day3/aoc.h | 100 |
2 files changed, 104 insertions, 1 deletions
diff --git a/src/2017/day3/aoc.cpp b/src/2017/day3/aoc.cpp index 85c2aa4..0142728 100644 --- a/src/2017/day3/aoc.cpp +++ b/src/2017/day3/aoc.cpp @@ -42,4 +42,9 @@ int day3(int target) { return d + p.first; } +int day3part2(int target) { + spiral_grid grid{9}; + return grid.fill_until(target); +} + } // namespace aoc2017 diff --git a/src/2017/day3/aoc.h b/src/2017/day3/aoc.h index be3159d..39ff51a 100644 --- a/src/2017/day3/aoc.h +++ b/src/2017/day3/aoc.h @@ -1,7 +1,105 @@ #pragma once #include "common.h" +#include <algorithm> +#include <vector> namespace aoc2017 { +struct spiral_grid { + int dim; + std::vector<int> cells; + + struct pos { + int x; + int y; + + bool operator>(pos other) const noexcept { return x > other.x && y == other.y; } + }; + + int get(pos p) const noexcept { + int x = dim / 2; + int y = dim / 2; + return (p.y + y) * dim + p.x + x; + } + + int value(pos p) const noexcept { + if (std::abs(p.x) > dim / 2 || std::abs(p.y) > dim / 2) { + return 0; + } + return cells[get(p)]; + } + + // 3, 5, 7, 9 + spiral_grid(int d) : dim(d), cells(dim * dim, 0) { + cells[get({0, 0})] = 1; + cells[get({1, 0})] = 1; + cells[get({1, -1})] = 2; + } + + pos last() const noexcept { return {dim / 2, dim / 2}; } + pos first() const noexcept { return {1, -1}; } + + static pos left(pos p) { return {p.x - 1, p.y}; } + static pos down(pos p) { return {p.x, p.y + 1}; } + static pos right(pos p) { return {p.x + 1, p.y}; } + static pos up(pos p) noexcept { return {p.x, p.y - 1}; } + + typedef pos (*mov)(pos); + + void collect(pos* p, std::vector<pos>& ps, mov f, int times) const noexcept { + while (times-- > 0) { + *p = f(*p); + ps.emplace_back(*p); + } + } + + std::vector<pos> circle() const noexcept { + // left, down, right, up + int sides[] = {2, 2, 3, 3}; + mov ms[] = {left, down, right, up}; + std::vector<pos> ps{}; + pos p = first(); + bool is_last{false}; + while (!is_last) { + for (int i : {0, 1, 2, 3}) { + collect(&p, ps, ms[i], sides[i]); + if (p > last()) { + is_last = true; + break; + } + sides[i] += 2; + } + } + return ps; + } + + int set(pos p) { + auto p1 = value({p.x, p.y + 1}); + auto p2 = value({p.x, p.y - 1}); + auto p3 = value({p.x - 1, p.y}); + auto p4 = value({p.x + 1, p.y}); + auto p5 = value({p.x + 1, p.y + 1}); + auto p6 = value({p.x + 1, p.y - 1}); + auto p7 = value({p.x - 1, p.y + 1}); + auto p8 = value({p.x - 1, p.y - 1}); + size_t i = get(p); + cells[i] = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8; + // printf("(%d, %d) -> %d (%d,%d,%d,%d,%d,%d,%d,%d)\n", p.x, p.y, cells[i], p1, p2, p3, p4, p5, p6, p7, p8); + return cells[i]; + } + + int fill_until(int t) { + auto ps = circle(); + for (auto& p : ps) { + int x = set(p); + if (x > t) { + return x; + } + } + return 0; + } +}; + int day3(int); -} +int day3part2(int); +} // namespace aoc2017 |