|
@ -2,6 +2,11 @@ |
|
|
#include <vector> |
|
|
#include <vector> |
|
|
#include <unordered_set> |
|
|
#include <unordered_set> |
|
|
|
|
|
|
|
|
|
|
|
//#define ANIMATE
|
|
|
|
|
|
#ifdef ANIMATE |
|
|
|
|
|
#include <fstream> |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
using namespace std; |
|
|
using namespace std; |
|
|
|
|
|
|
|
|
enum Dir { |
|
|
enum Dir { |
|
@ -71,6 +76,50 @@ Input parse() |
|
|
return data; |
|
|
return data; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef ANIMATE |
|
|
|
|
|
bool animate; |
|
|
|
|
|
int min_x, max_x, min_y, max_y; |
|
|
|
|
|
unsigned frame; |
|
|
|
|
|
void output_img(const vector<Pos2d> &knot, const unordered_set<Pos2d> &visited) |
|
|
|
|
|
{ |
|
|
|
|
|
enum Grid { |
|
|
|
|
|
NONE, |
|
|
|
|
|
VISITED, |
|
|
|
|
|
TAIL, |
|
|
|
|
|
HEAD |
|
|
|
|
|
}; |
|
|
|
|
|
unsigned width = max_x - min_x; |
|
|
|
|
|
unsigned height = max_y - min_y; |
|
|
|
|
|
auto map = vector<enum Grid>(width * height); |
|
|
|
|
|
|
|
|
|
|
|
for (auto i : visited) map[(i.y - min_y) * width + (i.x - min_x)] = VISITED; |
|
|
|
|
|
for (auto i : knot) map[(i.y - min_y) * width + (i.x - min_x)] = TAIL; |
|
|
|
|
|
map[(knot.front().y - min_y) * width + (knot.front().x - min_x)] = HEAD; |
|
|
|
|
|
|
|
|
|
|
|
char fname[] = "img/00000.pam"; |
|
|
|
|
|
sprintf(fname, "img/%05d.pam", frame++); |
|
|
|
|
|
auto file = ofstream(fname); |
|
|
|
|
|
file << "P7\n"; |
|
|
|
|
|
file << "WIDTH " << width << "\n"; |
|
|
|
|
|
file << "HEIGHT " << height << "\n"; |
|
|
|
|
|
file << "DEPTH 3\n"; |
|
|
|
|
|
file << "MAXVAL 255\n"; |
|
|
|
|
|
file << "TUPLTYPE RGB\n"; |
|
|
|
|
|
file << "ENDHDR\n"; |
|
|
|
|
|
for (auto i : map) { |
|
|
|
|
|
uint32_t color = 0; |
|
|
|
|
|
switch (i) { |
|
|
|
|
|
case NONE: color = 0x000000; break; |
|
|
|
|
|
case VISITED: color = 0xFF0000; break; |
|
|
|
|
|
case TAIL: color = 0x00FF00; break; |
|
|
|
|
|
case HEAD: color = 0x0000FF; break; |
|
|
|
|
|
} |
|
|
|
|
|
file.write((char *)&color, 3); |
|
|
|
|
|
} |
|
|
|
|
|
file.close(); |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
unsigned p1(const Input &input, unsigned count = 2) |
|
|
unsigned p1(const Input &input, unsigned count = 2) |
|
|
{ |
|
|
{ |
|
|
auto knot = vector<Pos2d>(count); |
|
|
auto knot = vector<Pos2d>(count); |
|
@ -90,6 +139,18 @@ unsigned p1(const Input &input, unsigned count = 2) |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
visited.insert(knot.back()); |
|
|
visited.insert(knot.back()); |
|
|
|
|
|
#ifdef ANIMATE |
|
|
|
|
|
if (!animate) { |
|
|
|
|
|
for (auto cur : knot) { |
|
|
|
|
|
if (cur.x < min_x) min_x = cur.x; |
|
|
|
|
|
if (cur.x > max_x) max_x = cur.x; |
|
|
|
|
|
if (cur.y < min_y) min_y = cur.y; |
|
|
|
|
|
if (cur.y > max_y) max_y = cur.y; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
output_img(knot, visited); |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return visited.size(); |
|
|
return visited.size(); |
|
@ -103,6 +164,13 @@ unsigned p2(const Input &input) |
|
|
int main() |
|
|
int main() |
|
|
{ |
|
|
{ |
|
|
auto input = parse(); |
|
|
auto input = parse(); |
|
|
|
|
|
#ifdef ANIMATE |
|
|
|
|
|
animate = false; |
|
|
|
|
|
p1(input, 10); |
|
|
|
|
|
animate = true; |
|
|
|
|
|
p1(input, 10); |
|
|
|
|
|
return 0; |
|
|
|
|
|
#endif |
|
|
cout << p1(input) << endl; |
|
|
cout << p1(input) << endl; |
|
|
cout << p2(input) << endl; |
|
|
cout << p2(input) << endl; |
|
|
} |
|
|
} |
|
|