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

#include <cassert>
#include <iostream>
#include <vector>

typedef size_t baumkuchen_size_t;
typedef int index_t;

std::vector<baumkuchen_size_t> pieces;
baumkuchen_size_t whole_size; // SUM OF SIZE OF PIECES
baumkuchen_size_t max_size;   // MAX SIZE OF THE SMALLEST PIECE

inline void reguralize(index_t *x) {
  if ((*x) < 0)
    (*x) += pieces.size();
  (*x) %= pieces.size();
}

inline void progress_idx(index_t &idx, baumkuchen_size_t &size_prev,
                         baumkuchen_size_t &size_curr) {
  size_prev += pieces.at(idx);
  size_curr -= pieces.at(idx);
  ++idx;
  reguralize(&idx);
}

inline void regress_idx(index_t &idx, baumkuchen_size_t &size_prev,
                        baumkuchen_size_t &size_curr) {
  --idx;
  reguralize(&idx);
  size_prev -= pieces.at(idx);
  size_curr += pieces.at(idx);
}

inline void update(baumkuchen_size_t input, baumkuchen_size_t *target) {
  if (input > (*target))
    (*target) = input;
}

int main() {
  // READ INPUTS
  {
    int num;
    std::cin >> num;
    pieces.assign(num, 0);

    for (int i = 0; i < num; ++i) {
      std::cin >> pieces[i];
      whole_size += pieces.at(i);
    }
    max_size = whole_size / 3;
  }

  index_t idx1(0), idx2(1), idx3(2); // BEGIN INDEX OF EACH BAUMKUCHEN PIECE
  baumkuchen_size_t size1(pieces.at(idx1)), // SIZE OF 1ST BAUMKUCHEN PIECE
      size2(pieces.at(idx2)),               // SIZE OF 2ND BAUMKUCHEN PIECE
      size3(whole_size - size1 - size2);    // SIZE OF 3RD BAUMKUCHEN PIECE
  baumkuchen_size_t out(0);                 // RETURN VALUE

  /* PRESUME THAT THE FIRST PIECE IS SMALLEST. */

  // std::cerr << "num = " << pieces.size() << std::endl;
  // std::cerr << "sum = " << whole_size << std::endl;
  // std::cerr << "max = " << max_size << std::endl;

  for (int i = 0; i < pieces.size(); ++i) {
    while (size1 <= max_size) {
      // CHECK WHETHER size1 CAN BE SMALLEST

      if (size1 <= size2 and size1 <= size3)
        update(size1, &out);

      while (size1 > size2 or size1 > size3) {
        // NOTE: size2 & size3 CANNOT BE EQUAL HERE.

        bool was_larger(size2 > size3);
        assert(size2 != size3);

        (size2 > size3) ? regress_idx(idx3, size2, size3)
                        : progress_idx(idx3, size2, size3);

        if (size1 <= size2 and size1 <= size3)
          update(size1, &out);

        if ((size2 > size3) != was_larger)
          break;
      }

      progress_idx(idx2, size1, size2);
    }

    progress_idx(idx1, size3, size1);
    while (size1 > max_size)
      regress_idx(idx2, size1, size2);
  }

  // std::cerr << "out = " << out << std::endl;
  std::cout << out << std::endl;

  return 0;
}

Error: 0
num = 6
sum = 21
max = 7
out = 6


Fixed submission:

#include <cassert>
#include <iostream>
#include <vector>

typedef size_t baumkuchen_size_t;
typedef int index_t;

std::vector<baumkuchen_size_t> pieces;
baumkuchen_size_t whole_size; // SUM OF SIZE OF PIECES
baumkuchen_size_t max_size;   // MAX SIZE OF THE SMALLEST PIECE

inline void reguralize(index_t *x) {
  if ((*x) < 0)
    (*x) += pieces.size();
  (*x) %= pieces.size();
}

inline void progress_idx(index_t &idx, baumkuchen_size_t &size_prev,
                         baumkuchen_size_t &size_curr) {
  size_prev += pieces.at(idx);
  size_curr -= pieces.at(idx);
  ++idx;
  reguralize(&idx);
}

inline void regress_idx(index_t &idx, baumkuchen_size_t &size_prev,
                        baumkuchen_size_t &size_curr) {
  --idx;
  reguralize(&idx);
  size_prev -= pieces.at(idx);
  size_curr += pieces.at(idx);
}

inline void update(baumkuchen_size_t input, baumkuchen_size_t *target) {
  if (input > (*target))
    (*target) = input;
}

int main() {
  // READ INPUTS
  {
    int num;
    std::cin >> num;
    pieces.assign(num, 0);

    for (int i = 0; i < num; ++i) {
      std::cin >> pieces[i];
      whole_size += pieces.at(i);
    }
    max_size = whole_size / 3;
  }

  index_t idx1(0), idx2(1), idx3(2); // BEGIN INDEX OF EACH BAUMKUCHEN PIECE
  baumkuchen_size_t size1(pieces.at(idx1)), // SIZE OF 1ST BAUMKUCHEN PIECE
      size2(pieces.at(idx2)),               // SIZE OF 2ND BAUMKUCHEN PIECE
      size3(whole_size - size1 - size2);    // SIZE OF 3RD BAUMKUCHEN PIECE
  baumkuchen_size_t out(0);                 // RETURN VALUE

  /* PRESUME THAT THE FIRST PIECE IS SMALLEST. */

  std::cerr << "num = " << pieces.size() << std::endl;
  std::cerr << "sum = " << whole_size << std::endl;
  std::cerr << "max = " << max_size << std::endl;

  for (int i = 0; i < pieces.size(); ++i) {
    while (size1 <= max_size) {
      // CHECK WHETHER size1 CAN BE SMALLEST

      if (size1 <= size2 and size1 <= size3)
        update(size1, &out);

      while (size1 > size2 or size1 > size3) {
        // NOTE: size2 & size3 CANNOT BE EQUAL HERE.

        bool was_larger(size2 > size3);
        assert(size2 != size3);

        (size2 > size3) ? regress_idx(idx3, size2, size3)
                        : progress_idx(idx3, size2, size3);

        if (size1 <= size2 and size1 <= size3)
          update(size1, &out);

        if ((size2 > size3) != was_larger)
          break;
      }

      progress_idx(idx2, size1, size2);
    }

    progress_idx(idx1, size3, size1);
    while (size1 > max_size)
      regress_idx(idx2, size1, size2);
  }

  std::cerr << "out = " << out << std::endl;
  std::cout << out << std::endl;

  return 0;
}