To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

Commit f057eada authored by amiessen's avatar amiessen
Browse files

added day 10, part 2

parent be67af62
......@@ -2,9 +2,14 @@
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <cassert>
void loadData(const std::string & data_path,
std::vector<std::vector<int>> & data)
{
......@@ -28,7 +33,11 @@ void loadData(const std::string & data_path,
}
bool sightBlocked(const std::vector<std::vector<int>> & coords,
// ##############
// --- PART 1 ---
// ##############
template<typename T>
bool sightBlocked(const std::vector<std::vector<T>> & coords,
size_t lookedFrom, size_t lookedAt)
{
assert(lookedAt < coords.size() && lookedFrom < coords.size());
......@@ -41,7 +50,7 @@ bool sightBlocked(const std::vector<std::vector<int>> & coords,
if yes -> blocked
*/
std::vector<int> conn(2);
std::vector<T> conn(2);
conn[0] = coords[lookedAt][0] - coords[lookedFrom][0];
conn[1] = coords[lookedAt][1] - coords[lookedFrom][1];
......@@ -54,7 +63,7 @@ bool sightBlocked(const std::vector<std::vector<int>> & coords,
end = lookedFrom;
}
std::vector<int> s(2);
std::vector<T> s(2);
for (size_t i = start+1; i < end; i++) {
// compute connecting vector ast_lookedFrom - ast_i
// ast_i is between ast_lookedFrom and ast_lookedAt
......@@ -91,8 +100,8 @@ void getAstsInSight(const std::vector<std::vector<int>> & coords,
}
int getMaxAsts(const std::vector<int> & astCount) {
int max = 0;
size_t getMaxAsts(const std::vector<int> & astCount) {
size_t max = 0;
for (size_t i = 0; i < astCount.size(); i++) {
if (astCount[i] > astCount[max]) { max = i; }
......@@ -102,20 +111,136 @@ int getMaxAsts(const std::vector<int> & astCount) {
}
// ##############
// --- PART 2 ---
// ##############
void cartToPolar(const std::vector<std::vector<int>> & coords,
const size_t station,
std::vector<std::vector<double>> & coordsPol)
{
// shift origin of coordinate system to station
// transform to polar coordinates
for (size_t i = 0; i < coords.size(); i++) {
// atan2(y,x) : R -> [-PI , PI] with phi=0 on +x axis and positive phi
// running counter clockwise
// atan2(x,y) for phi = 0 on +y axis and positive phi running clockwise
// atan2(x,-y) necessary since coordinate +y axis is pointing down
double phi = atan2((coords[i][0]-coords[station][0]),
-(coords[i][1]-coords[station][1]));
// phi in [0, 2 PI] instead of [-PI, PI]
phi = (phi >= 0 ? phi : (2*M_PI + phi));
double r = sqrt(
(coords[i][0]-coords[station][0])*(coords[i][0]-coords[station][0])
+ (coords[i][1]-coords[station][1])*(coords[i][1]-coords[station][1]));
coordsPol[i] = std::vector<double>{phi,r};
}
}
void vaporizeAsts(const std::vector<std::vector<int>> & coords,
const size_t station, std::vector<size_t> & vapIdx)
{
int N = coords.size();
std::vector<bool> vaporized(N, false);
int vapCount = 0;
// convert coords to polar coordinates with phi = 0 pointing up along
// +y axis and increasing clockwise. coordsPol[i][0] = phi, ..[i][1] = r
std::vector<std::vector<double>> coordsPol(coords.size());
cartToPolar(coords, station, coordsPol);
// create vector of indices, sort such that coordsPol are in order of
// ascending azimuthal angle phi if accessed with indices in order of
// sorted vector idx
std::vector<size_t> idx(N);
std::iota(idx.begin(), idx.end(), 0);
std::sort(idx.begin(), idx.end(),
[& coordsPol](size_t i1, size_t i2) {
return coordsPol[i1][0] < coordsPol[i2][0];
});
// erase station itself from index list
idx.erase(idx.begin());
// sort vector idx such that coordsPol[idx[i]][1] gives increasing order of
// radii r WITHIN series of equal azimuthal angles phi (coordsPol[idx[i]][0])
size_t ir = 0;
while (ir < idx.size()-1) {
size_t end = 0;
size_t start = ir;
while (coordsPol[idx[ir]][0] == coordsPol[idx[ir+1]][0] ) {
end++;
ir++;
}
end++;
std::sort(idx.begin()+start, idx.begin()+start+end,
[& coordsPol](size_t i1, size_t i2) {
return coordsPol[i1][1] < coordsPol[i2][1];
});
ir++;
}
// vaporize all asteroids (N-1 without station)
while (vapCount < N-1) {
// remove from vector idx all vaporized asteroids
idx.erase(std::remove_if(idx.begin(), idx.end(),
[& vaporized](size_t i)
{ return vaporized[i]; }),
idx.end());
if (idx.size() > 0) {
vapIdx[vapCount] = idx[0];
vaporized[idx[0]] = true;
vapCount++;
}
for (size_t i = 1; i < idx.size(); i++) {
if (coordsPol[idx[i]][0] == coordsPol[idx[i-1]][0]) {
continue;
} else {
vapIdx[vapCount] = idx[i];
vaporized[idx[i]] = true;
vapCount++;
}
}
} // WHILE: vapCount < N-1
}
// ##############
// ### MAIN ###
// ##############
int main() {
std::string data_path = "in10.txt";
std::vector<std::vector<int>> coords;
loadData(data_path, coords);
std::cout << "\n - - - PART 1 - - - \n";
std::vector<int> astCount(coords.size());
getAstsInSight(coords, astCount);
int indexMax = getMaxAsts(astCount);
size_t station = getMaxAsts(astCount);
std::cout << "Asteroid with maximum number of other asteroids in sight:\n";
std::cout << "(X,Y) = (" << coords[indexMax][0] << ","
<< coords[indexMax][1] << ") with " << astCount[indexMax]
std::cout << "(X,Y) = (" << coords[station][0] << ","
<< coords[station][1] << ") with " << astCount[station]
<< " asteroids in sight\n";
std::cout << "\n - - - PART 2 - - - \n";
std::vector<size_t> vapIdx(coords.size());
vaporizeAsts(coords, station, vapIdx);
std::cout << "Asteroid " << 200 << " vaporized at "
<< coords[vapIdx[199]][0] << "," << coords[vapIdx[199]][1] << "\t- ";
std::cout << "100*X + Y = "
<< coords[vapIdx[199]][0]*100+coords[vapIdx[199]][1] << "\n";
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment