Skip to content

Commit cb9be9d

Browse files
committedDec 20, 2021
Day 17, part 2 implemented
1 parent 160f32c commit cb9be9d

File tree

2 files changed

+238
-0
lines changed

2 files changed

+238
-0
lines changed
 

‎day17/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
default:
22
c++ -I../ -o bin/p1 src/p1.cpp ../lib/io.cpp
3+
c++ -I../ -o bin/p2 src/p2.cpp ../lib/io.cpp

‎day17/src/p2.cpp

+237
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <string>
4+
#include <vector>
5+
#include "lib/io.h"
6+
7+
#include <sstream>
8+
9+
using namespace std;
10+
11+
class Point {
12+
public:
13+
double x;
14+
double y;
15+
16+
Point() {
17+
x = 0;
18+
y = 0;
19+
}
20+
21+
Point(double x, double y) {
22+
this->x = x;
23+
this->y = y;
24+
}
25+
26+
string to_string() {
27+
return std::to_string(int(x)) + ":" + std::to_string(int(y));
28+
}
29+
};
30+
31+
class Velocity {
32+
public:
33+
int x;
34+
int y;
35+
36+
Velocity() {}
37+
38+
Velocity(int x, int y) {
39+
this->x = x;
40+
this->y = y;
41+
}
42+
43+
void parse(string s) {
44+
int pos = s.find(",");
45+
x = stoi(s.substr(0, pos));
46+
y = stoi(s.substr(pos + 1));
47+
}
48+
49+
string to_string() {
50+
return std::to_string(x) + "," + std::to_string(y);
51+
}
52+
};
53+
54+
class Probe {
55+
public:
56+
Point location;
57+
Velocity velocity;
58+
59+
Probe() {
60+
this->location = Point();
61+
this->velocity = Velocity();
62+
}
63+
64+
void step() {
65+
location.x += velocity.x;
66+
location.y += velocity.y;
67+
68+
if (velocity.x > 0) {
69+
velocity.x -= 1;
70+
} else if (velocity.x < 0) {
71+
velocity.x += 1;
72+
}
73+
74+
velocity.y -= 1;
75+
}
76+
77+
string to_string() {
78+
stringbuf buffer;
79+
ostream os (&buffer);
80+
81+
os << location.x << "," << location.y << " (" << velocity.x << "," << velocity.y << ")";
82+
83+
return buffer.str();
84+
}
85+
};
86+
87+
const int TEXT_LENGTH=13;
88+
89+
class Target {
90+
public:
91+
int x_start;
92+
int x_end;
93+
int y_start;
94+
int y_end;
95+
96+
void parse(string line) {
97+
string xydata = line.substr(TEXT_LENGTH);
98+
int pos = xydata.find(", ");
99+
string xpart = xydata.substr(2, pos - 2);
100+
string ypart = xydata.substr(pos + 4);
101+
int xsep = xpart.find("..");
102+
x_start = stoi(xpart.substr(0, xsep));
103+
x_end = stoi(xpart.substr(xsep + 2));
104+
105+
int ysep = ypart.find("..");
106+
y_start = stoi(ypart.substr(0, ysep));
107+
y_end = stoi(ypart.substr(ysep + 2));
108+
}
109+
110+
bool in_bounds(Point p) {
111+
bool in_x = p.x >= x_start && p.x <= x_end;
112+
bool in_y = p.y >= y_start && p.y <= y_end;
113+
return in_x && in_y;
114+
}
115+
116+
bool beyond_bounds(Point p) {
117+
return beyond_x(p) || beyond_y(p);
118+
}
119+
120+
bool beyond_x(Point p) {
121+
return p.x > x_end;
122+
}
123+
124+
bool beyond_y(Point p) {
125+
return p.y < y_start;
126+
}
127+
128+
string to_string() {
129+
stringbuf buffer;
130+
ostream os (&buffer);
131+
132+
os << x_start << ".." << x_end << ", " << y_start << ".." << y_end;
133+
134+
return buffer.str();
135+
}
136+
};
137+
138+
class Result {
139+
public:
140+
int max_height = 0;
141+
bool hit;
142+
bool beyond_x;
143+
bool beyond_y;
144+
145+
bool beyond() {
146+
return beyond_x || beyond_y;
147+
}
148+
};
149+
150+
void print_debug_info(Result *r, Probe *p) {
151+
if (r->hit) {
152+
cout << "Probe hit (maxh=" << r->max_height << "): " << p->to_string() << endl;
153+
} else if (r->beyond()) {
154+
cout << "Probe went beyond (x:" << r->beyond_x << ",y:" << r->beyond_y << "): " << p->to_string() << endl;
155+
}
156+
157+
cout << "Max height: " << r->max_height << endl;
158+
159+
}
160+
161+
Result fire_probe(Probe *p, Target t) {
162+
Result r;
163+
do {
164+
p->step();
165+
if (p->location.y > r.max_height) r.max_height = p->location.y;
166+
r.hit = t.in_bounds(p->location);
167+
r.beyond_x = t.beyond_x(p->location);
168+
r.beyond_y = t.beyond_y(p->location);
169+
} while (!r.hit && !r.beyond());
170+
171+
return r;
172+
}
173+
174+
int main (int argc, char** argv) {
175+
string filename;
176+
Velocity initial_velocity;
177+
bool use_initial_velocity = false;
178+
179+
if (argc != 2 && argc != 3) {
180+
cout << "Usage: " << argv[0] << " datafile velocity" << endl;
181+
return 1;
182+
} else {
183+
filename = argv[1];
184+
if (argc == 3) {
185+
use_initial_velocity = true;
186+
initial_velocity.parse(argv[2]);
187+
}
188+
}
189+
190+
vector<string> data = read_data(filename);
191+
cout << "Loaded " << data.size() << " data lines" << endl;
192+
193+
Target t;
194+
t.parse(data[0]);
195+
cout << "Target range: " << t.to_string() << endl;
196+
197+
Probe p;
198+
if (use_initial_velocity) {
199+
cout << "Fire probe with initial velocity given: " << initial_velocity.to_string() << endl;
200+
p.velocity = initial_velocity;
201+
202+
cout << "Probe:" << p.to_string() << endl;
203+
204+
Result r = fire_probe(&p, t);
205+
206+
print_debug_info(&r, &p);
207+
} else {
208+
cout << "Fire probe until all hits determined" << endl;
209+
210+
int x = 1;
211+
int hit_count = 0;
212+
Result r;
213+
214+
while (x <= t.x_end) {
215+
// cout << "X = " << x << endl;
216+
int y = t.y_start;
217+
do {
218+
//cout << "Y = " << y << endl;
219+
p.location = Point(0, 0);
220+
p.velocity = Velocity(x, y);
221+
// cout << "Firing probe with velocity " << p.velocity.to_string() << endl;
222+
r = fire_probe(&p, t);
223+
if (r.hit) hit_count += 1;
224+
225+
y++;
226+
227+
} while (y <= abs(t.y_start));
228+
229+
x += 1;
230+
}
231+
cout << "Hit count: " << hit_count << endl;
232+
}
233+
234+
cout << "Done" << endl;
235+
236+
return 0;
237+
}

0 commit comments

Comments
 (0)
Please sign in to comment.