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

#include <cassert>
#include <iostream>
#ifndef LIB_REPEAT_HPP
#define LIB_REPEAT_HPP
#define repeat(i, n) for (int i = 0; i < (n); ++i)
#define repeat_from(i, m, n) for (int i = (m); i < (n); ++i)
#define repeat_one(i, n) for (int i = 1; i <= (n); ++i)
#define repeat_rev(i, n) for (int i = (n)-1; 0 <= i; --i)
#define foreach(it, cont)                                                      \\
  for (decltype(cont.begin()) it = cont.begin(); it != cont.end(); ++it)
#endif
#include <cmath>
#include <utility>
#include <vector>
#ifndef LIB_REPEAT_HPP
#define LIB_REPEAT_HPP
#define repeat(i, n) for (int i = 0; i < (n); ++i)
#define repeat_from(i, m, n) for (int i = (m); i < (n); ++i)
#define repeat_one(i, n) for (int i = 1; i <= (n); ++i)
#define repeat_rev(i, n) for (int i = (n)-1; 0 <= i; --i)
#define foreach(it, cont)                                                      \\
  for (decltype(cont.begin()) it = cont.begin(); it != cont.end(); ++it)
#endif
#ifndef LIB_DEBUG_HPP
#define LIB_DEBUG_HPP
#ifdef DEBUG
#include <cassert>
#define debug(a) a
#else
#define debug(a)
#endif
#endif
std::pair<std::vector<double>, int>
gaussian_elim_plus(std::vector<std::vector<double>> a) {
  const double eps = 1e-5;
  const int n = a.size();
  if (n == 0)
    return std::make_pair(std::vector<double>(0), 0);
  const int m = a[0].size();
#ifdef DEBUG
  repeat(i, n) assert((int)a[i].size() == m);
#endif
  std::vector<std::vector<double>> indep;
  int i = 0, j = 0;
  while (i < n and j < m - 1) {
    int pivot = -1;
    repeat_from(k, i, n) {
      if (eps < std::abs(a[k][j])) {
        // pivot = k; break;
        pivot = pivot == -1
                    ? k
                    : (std::abs(a[pivot][j]) < std::abs(a[k][j]) ? k : pivot);
      }
    }
    if (pivot == -1) {
      repeat(k, m) {
        if (eps < std::abs(a[i][k])) {
          if (k == m - 1) {
            return std::make_pair(std::vector<double>(0), -1);
          } else {
            j += 1;
            i -= 1; // dont incr i
            break;
          }
        }
      }
      i += 1;
      continue;
    } else {
      if (pivot != i)
        std::swap(a[i], a[pivot]);
      repeat_from(j, i + 1, m) a[i][j] /= a[i][i];
      a[i][i] = 1;
      repeat_from(j, i + 1, n) {
        repeat_from(k, i + 1, m) { a[j][k] -= a[j][i] * a[i][k]; }
        a[j][i] = 0;
      }
      indep.push_back(a[i]);
      i += 1;
      j += 1;
    }
  }
  while (i < n) {
    if (eps < std::abs(a[i][m - 1])) {
      return std::make_pair(std::vector<double>(0), -1);
    }
    i += 1;
  }
  if ((int)indep.size() < m - 1)
    return std::make_pair(std::vector<double>(0), indep.size());
#ifdef DEBUG
  assert((int)indep.size() == m - 1);
#endif
  // gather the solutions
  std::vector<double> result(m - 1);
  repeat_rev(i, m - 1) {
    result[i] = indep[i][m - 1];
    repeat_from(j, i + 1, m - 1) { result[i] -= indep[i][j] * result[j]; }
  }
  return std::make_pair(result, m - 1);
}

// a11x1 + a12x2 + ... + a1m-1xm-1 = a1m
// a21x1 + a22x2 + ... + a2m-1xm-1 = a2m
//      ...        ...            ...
// an1x1 + an2x2 + ... + anm-1xm-1 = anm
std::vector<double> gaussian_elim(std::vector<std::vector<double>> a) {
  return gaussian_elim_plus(a).first;
}
using namespace std;
int solve(int d, vector<double> &f, vector<vector<double>> &a) {
  vector<double> b(a[0].size(), 0);
  repeat(wrong, d + 3) {
    a[wrong].swap(b);
    if (gaussian_elim_plus(a).second != -1) {
      return wrong;
    }
  }
  assert(false);
}
int main() {
  ios_base::sync_with_stdio(false);
  while (true) {
    int d;
    cin >> d;
    if (d == 0)
      break;
    vector<double> f(d + 3);
    repeat(i, d + 3) cin >> f[i];
    vector<vector<double>> a(d + 3, vector<double>(d + 2));
    repeat(i, d + 3) repeat(j, d + 2) {
      a[i][j] = (0 <= d - j) ? pow(i, d - j) : f[i];
    }
    cout << solve(d, f, a) << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <cassert>
#include <iostream>
#ifndef LIB_REPEAT_HPP
#define LIB_REPEAT_HPP
#define repeat(i, n) for (int i = 0; i < (n); ++i)
#define repeat_from(i, m, n) for (int i = (m); i < (n); ++i)
#define repeat_one(i, n) for (int i = 1; i <= (n); ++i)
#define repeat_rev(i, n) for (int i = (n)-1; 0 <= i; --i)
#define foreach(it, cont)                                                      \\
  for (decltype(cont.begin()) it = cont.begin(); it != cont.end(); ++it)
#endif
#include <cmath>
#include <utility>
#include <vector>
#ifndef LIB_REPEAT_HPP
#define LIB_REPEAT_HPP
#define repeat(i, n) for (int i = 0; i < (n); ++i)
#define repeat_from(i, m, n) for (int i = (m); i < (n); ++i)
#define repeat_one(i, n) for (int i = 1; i <= (n); ++i)
#define repeat_rev(i, n) for (int i = (n)-1; 0 <= i; --i)
#define foreach(it, cont)                                                      \\
  for (decltype(cont.begin()) it = cont.begin(); it != cont.end(); ++it)
#endif
#ifndef LIB_DEBUG_HPP
#define LIB_DEBUG_HPP
#ifdef DEBUG
#include <cassert>
#define debug(a) a
#else
#define debug(a)
#endif
#endif
std::pair<std::vector<double>, int>
gaussian_elim_plus(std::vector<std::vector<double>> a) {
  const double eps = 1e-4;
  const int n = a.size();
  if (n == 0)
    return std::make_pair(std::vector<double>(0), 0);
  const int m = a[0].size();
#ifdef DEBUG
  repeat(i, n) assert((int)a[i].size() == m);
#endif
  std::vector<std::vector<double>> indep;
  int i = 0, j = 0;
  while (i < n and j < m - 1) {
    int pivot = -1;
    repeat_from(k, i, n) {
      if (eps < std::abs(a[k][j])) {
        pivot = k;
        break;
        // pivot = pivot == - 1 ? k : (std::abs(a[pivot][j]) < std::abs(a[k][j])
        // ? k : pivot);
      }
    }
    if (pivot == -1) {
      repeat(k, m) {
        if (eps < std::abs(a[i][k])) {
          if (k == m - 1) {
            return std::make_pair(std::vector<double>(0), -1);
          } else {
            j += 1;
            i -= 1; // dont incr i
            break;
          }
        }
      }
      i += 1;
      continue;
    } else {
      if (pivot != i)
        std::swap(a[i], a[pivot]);
      repeat_from(j, i + 1, m) a[i][j] /= a[i][i];
      a[i][i] = 1;
      repeat_from(j, i + 1, n) {
        repeat_from(k, i + 1, m) { a[j][k] -= a[j][i] * a[i][k]; }
        a[j][i] = 0;
      }
      indep.push_back(a[i]);
      i += 1;
      j += 1;
    }
  }
  while (i < n) {
    if (eps < std::abs(a[i][m - 1])) {
      return std::make_pair(std::vector<double>(0), -1);
    }
    i += 1;
  }
  if ((int)indep.size() < m - 1)
    return std::make_pair(std::vector<double>(0), indep.size());
#ifdef DEBUG
  assert((int)indep.size() == m - 1);
#endif
  // gather the solutions
  std::vector<double> result(m - 1);
  repeat_rev(i, m - 1) {
    result[i] = indep[i][m - 1];
    repeat_from(j, i + 1, m - 1) { result[i] -= indep[i][j] * result[j]; }
  }
  return std::make_pair(result, m - 1);
}

// a11x1 + a12x2 + ... + a1m-1xm-1 = a1m
// a21x1 + a22x2 + ... + a2m-1xm-1 = a2m
//      ...        ...            ...
// an1x1 + an2x2 + ... + anm-1xm-1 = anm
std::vector<double> gaussian_elim(std::vector<std::vector<double>> a) {
  return gaussian_elim_plus(a).first;
}
using namespace std;
int solve(int d, vector<double> &f, vector<vector<double>> &a) {
  vector<double> b(a[0].size(), 0);
  repeat(wrong, d + 3) {
    a[wrong].swap(b);
    if (gaussian_elim_plus(a).second != -1) {
      return wrong;
    }
  }
  assert(false);
}
int main() {
  ios_base::sync_with_stdio(false);
  while (true) {
    int d;
    cin >> d;
    if (d == 0)
      break;
    vector<double> f(d + 3);
    repeat(i, d + 3) cin >> f[i];
    vector<vector<double>> a(d + 3, vector<double>(d + 2));
    repeat(i, d + 3) repeat(j, d + 2) {
      a[i][j] = (0 <= d - j) ? pow(i, d - j) : f[i];
    }
    cout << solve(d, f, a) << endl;
  }
  return 0;
}