-
Notifications
You must be signed in to change notification settings - Fork 0
/
day9.cpp
104 lines (88 loc) · 2.62 KB
/
day9.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// Created by Johannes Loepelmann on 09.12.22.
//
#include <set>
#include "util.h"
const int max_width = 1024;
enum Direction {
UP, DOWN, LEFT, RIGHT
};
struct Instruction {
Direction dir;
int steps;
explicit Instruction(const std::string &input) {
switch (input[0]) {
case 'U':
dir = UP;
break;
case 'D':
dir = DOWN;
break;
case 'L':
dir = LEFT;
break;
case 'R':
dir = RIGHT;
}
steps = std::stoi(input.substr(1));
}
};
struct Position {
int x = 0, y = 0;
bool operator<(const Position &lhs) const {
return x * max_width + y < lhs.x * max_width + lhs.y;
}
};
bool touching(const Position first, const Position second) {
return (abs(first.x - second.x) < 2 && abs(first.y - second.y) < 2);
}
std::vector<Position> move(const Instruction ins, std::vector<Position> &snake) {
std::vector<Position> result;
auto &h = snake.front();
for (int i = 0; i < ins.steps; ++i) {
switch (ins.dir) {
case UP:
h.y += 1;
break;
case DOWN:
h.y -= 1;
break;
case LEFT:
h.x -= 1;
break;
case RIGHT:
h.x += 1;
break;
}
for (auto it = snake.begin(); it < snake.end() - 1; ++it) {
auto &front = *it;
auto &back = *(it + 1);
auto x_dir = std::clamp(front.x - back.x, -1, 1);
auto y_dir = std::clamp(front.y - back.y, -1, 1);
if (!touching(front, back)) {
back.x += x_dir;
back.y += y_dir;
}
}
result.push_back(snake.back());
}
return result;
}
int main() {
const auto lines = read_strings_from_file("day9.input");
std::set<Position> visited_short;
std::set<Position> visited_long;
Position s;
visited_short.insert(s);
visited_long.insert(s);
std::vector<Position> short_snake = {s, s};
std::vector<Position> long_snake = {s, s, s, s, s, s, s, s, s, s};
for (const auto &line: lines) {
Instruction current(line);
const auto vis_short = move(current, short_snake);
visited_short.insert(vis_short.begin(), vis_short.end());
const auto vis_long = move(current, long_snake);
visited_long.insert(vis_long.begin(), vis_long.end());
}
std::cout << "Count short: " << visited_short.size() << " Count long: " << visited_long.size() << std::endl;
}