Problem p00868 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
const double INF = (1e15), EPS = (1e-10);

struct P {
  double X, Y, Z;
};

P operator+(P a, P b) { return (P){a.X + b.X, a.Y + b.Y, a.Z + b.Z}; }
P operator*(P a, double c) { return (P){a.X * c, a.Y * c, a.Z * c}; }
P operator*(double c, P a) { return a * c; }
P operator/(P a, double c) { return a * (1 / c); }
P operator/(double c, P a) { return a * (1 / c); }
P operator-(P a) { return -1 * a; }
P operator-(P a, P b) { return a + (-b); }

double dot(P a, P b) { return a.X * b.X + a.Y * b.Y + a.Z * b.Z; }
double len(P a) { return sqrt(dot(a, a)); }
P projection(P a, P b) { return b / len(b) * dot(a, b / len(b)); }
P line_symmetry(P x, P a, P b) {
  return 2 * a + 2 * projection(x - a, b - a) - x;
}

int main() {
  int N;
  while (cin >> N, N) {
    double u, v, w;
    cin >> u >> v >> w;
    P d = {u, v, w};
    vector<P> V;
    vector<double> R(N);
    for (int i = 0; i < N; ++i) {
      double x, y, z, r;
      cin >> x >> y >> z >> r;
      V.push_back((P){x, y, z});
      R[i] = r;
    }
    P p = {0, 0, 0};
    while (1) {
      int id = -1;
      double l = INF;
      for (int i = 0; i < N; ++i) {
        if (dot(d, V[i] - p) < EPS)
          continue;
        P proj = projection(V[i] - p, d);
        double r = R[i];
        if (dot(V[i] - p, V[i] - p) - dot(proj, proj) > r * r + EPS)
          continue;
        double l_ =
            len(proj) - sqrt(r * r - dot(V[i] - p, V[i] - p) + dot(proj, proj));
        // cerr << i << "; " << l_ << endl;
        if (l_ > EPS && l_ < l) {
          l = l_;
          id = i;
        }
      }
      if (id < 0)
        break;
      P q = p + l / len(d) * d;
      // assert(dot(q-V[id],q-V[id]) - R[id]*R[id] < EPS);
      // printf("Error = %.12f\\n",dot(q-V[id],q-V[id]) - R[id]*R[id]);
      d = line_symmetry(p, V[id], q) - q;
      p = q;
      // cerr << id << " ; ";
      // cerr << "(" << p.X << ", " << p.Y << ", " << p.Z << "), ";
      // cerr << "(" << q.X << ", " << q.Y << ", " << q.Z << ")" << endl;
    }
    printf("%.12f %.12f %.12f\\n", p.X, p.Y, p.Z);
  }
  return 0;
}


Error: WA

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
const double INF = (1e15), EPS = (1e-10);

struct P {
  double X, Y, Z;
};

P operator+(P a, P b) { return (P){a.X + b.X, a.Y + b.Y, a.Z + b.Z}; }
P operator*(P a, double c) { return (P){a.X * c, a.Y * c, a.Z * c}; }
P operator*(double c, P a) { return a * c; }
P operator/(P a, double c) { return a * (1 / c); }
P operator/(double c, P a) { return a * (1 / c); }
P operator-(P a) { return -1 * a; }
P operator-(P a, P b) { return a + (-b); }

double dot(P a, P b) { return a.X * b.X + a.Y * b.Y + a.Z * b.Z; }
double len(P a) { return sqrt(dot(a, a)); }
P projection(P a, P b) { return b / len(b) * dot(a, b / len(b)); }
P line_symmetry(P x, P a, P b) {
  return 2 * a + 2 * projection(x - a, b - a) - x;
}

int main() {
  int N;
  while (cin >> N, N) {
    double u, v, w;
    cin >> u >> v >> w;
    P d = {u, v, w};
    vector<P> V;
    vector<double> R(N);
    for (int i = 0; i < N; ++i) {
      double x, y, z, r;
      cin >> x >> y >> z >> r;
      V.push_back((P){x, y, z});
      R[i] = r;
    }
    P p = {0, 0, 0};
    while (1) {
      int id = -1;
      double l = INF;
      for (int i = 0; i < N; ++i) {
        if (dot(d, V[i] - p) < EPS)
          continue;
        P proj = projection(V[i] - p, d);
        double r = R[i];
        if (dot(V[i] - p, V[i] - p) - dot(proj, proj) > r * r + EPS)
          continue;
        double l_ =
            len(proj) - sqrt(r * r - dot(V[i] - p, V[i] - p) + dot(proj, proj));
        cerr << i << "; " << l_ << endl;
        if (l_ > EPS && l_ < l) {
          l = l_;
          id = i;
        }
      }
      if (id < 0)
        break;
      P q = p + l / len(d) * d;
      // assert(dot(q-V[id],q-V[id]) - R[id]*R[id] < EPS);
      // printf("Error = %.12f\\n",dot(q-V[id],q-V[id]) - R[id]*R[id]);
      d = line_symmetry(p, V[id], q) - q;
      p = q;
      cerr << id << " ; ";
      cerr << "(" << p.X << ", " << p.Y << ", " << p.Z << "), ";
      cerr << "(" << q.X << ", " << q.Y << ", " << q.Z << ")" << endl;
    }
    printf("%.12f %.12f %.12f\\n", p.X, p.Y, p.Z);
  }
  return 0;
}