Problem p02386 (C++)

Buggy submission (status: Runtime Error):
#include <array>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

constexpr int SURFACE_NUM = 6;
enum { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM };

class Dice {
private:
  array<int, SURFACE_NUM> m_surface;

public:
  // constructor
  Dice(array<int, SURFACE_NUM> surface) : m_surface(surface) {}

  // getter
  int surface(int i) const { return m_surface.at(i); }

  // roll and spin
  void roll(char direction) {
    switch (direction) {
    case 'N':
      roll(TOP, FRONT, BOTTOM, BACK);
      break;
    case 'S':
      roll(TOP, BACK, BOTTOM, FRONT);
      break;
    case 'E':
      roll(TOP, LEFT, BOTTOM, RIGHT);
      break;
    case 'W':
      roll(TOP, RIGHT, BOTTOM, LEFT);
      break;
    }
  }

  void roll(int i, int j, int k, int l) {
    int tmp = m_surface.at(i);
    m_surface.at(i) = m_surface.at(j);
    m_surface.at(j) = m_surface.at(k);
    m_surface.at(k) = m_surface.at(l);
    m_surface.at(l) = tmp;
  }

  void spin() {
    int tmp = m_surface.at(FRONT);
    m_surface.at(FRONT) = m_surface.at(LEFT);
    m_surface.at(LEFT) = m_surface.at(BACK);
    m_surface.at(BACK) = m_surface.at(RIGHT);
    m_surface.at(RIGHT) = tmp;
  }

  // is equal
  bool isEqual(const Dice &dice) {
    for (int i = 0; i < 6; i++) {
      (i % 2) ? (*this).roll('E') : (*this).roll('N');
      for (int j = 0; j < 4; j++) {
        (*this).spin();
        if (*this == dice) {
          return true;
        }
      }
    }
    return false;
  }

  bool operator==(const Dice &dice) {
    for (int i = 0; i < SURFACE_NUM; i++) {
      if (m_surface.at(i) != dice.surface(i)) {
        return false;
      }
    }
    return true;
  }

  // debug
  void printDice() const {
    cout << surface(TOP) << surface(FRONT) << surface(RIGHT) << surface(LEFT)
         << surface(BACK) << surface(BOTTOM) << endl;
  }
};

array<int, SURFACE_NUM> inputDice();

int main() {
  int dice_num;
  cin >> dice_num;

  vector<Dice> dices;
  dices.reserve(dice_num);
  for (auto i = 0; i < dice_num; i++) {
    Dice dice(inputDice());
    dices.at(i) = dice;
  }

  bool is_diff_all = true;
  for (int i = 0; i < dice_num - 1 && is_diff_all; i++) {
    for (int j = i + 1; j < dice_num; j++) {
      if (dices.at(i).isEqual(dices.at(j))) {
        is_diff_all = false;
        break;
      }
    }
  }

  cout << (is_diff_all ? "Yes" : "No") << endl;
}

array<int, SURFACE_NUM> inputDice() {
  array<int, SURFACE_NUM> init;
  for (auto i = 0; i < SURFACE_NUM; i++) {
    cin >> init.at(i);
  }
  return init;
}

Fixed submission:
#include <array>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

constexpr int SURFACE_NUM = 6;
enum { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM };

class Dice {
private:
  array<int, SURFACE_NUM> m_surface;

public:
  // constructor
  Dice(array<int, SURFACE_NUM> surface) : m_surface(surface) {}

  // getter
  int surface(int i) const { return m_surface.at(i); }

  // roll and spin
  void roll(char direction) {
    switch (direction) {
    case 'N':
      roll(TOP, FRONT, BOTTOM, BACK);
      break;
    case 'S':
      roll(TOP, BACK, BOTTOM, FRONT);
      break;
    case 'E':
      roll(TOP, LEFT, BOTTOM, RIGHT);
      break;
    case 'W':
      roll(TOP, RIGHT, BOTTOM, LEFT);
      break;
    }
  }

  void roll(int i, int j, int k, int l) {
    int tmp = m_surface.at(i);
    m_surface.at(i) = m_surface.at(j);
    m_surface.at(j) = m_surface.at(k);
    m_surface.at(k) = m_surface.at(l);
    m_surface.at(l) = tmp;
  }

  void spin() {
    int tmp = m_surface.at(FRONT);
    m_surface.at(FRONT) = m_surface.at(LEFT);
    m_surface.at(LEFT) = m_surface.at(BACK);
    m_surface.at(BACK) = m_surface.at(RIGHT);
    m_surface.at(RIGHT) = tmp;
  }

  // is equal
  bool isEqual(const Dice &dice) {
    for (int i = 0; i < 6; i++) {
      (i % 2) ? (*this).roll('E') : (*this).roll('N');
      for (int j = 0; j < 4; j++) {
        (*this).spin();
        if (*this == dice) {
          return true;
        }
      }
    }
    return false;
  }

  bool operator==(const Dice &dice) {
    for (int i = 0; i < SURFACE_NUM; i++) {
      if (m_surface.at(i) != dice.surface(i)) {
        return false;
      }
    }
    return true;
  }

  // debug
  void printDice() const {
    cout << surface(TOP) << surface(FRONT) << surface(RIGHT) << surface(LEFT)
         << surface(BACK) << surface(BOTTOM) << endl;
  }
};

array<int, SURFACE_NUM> inputDice();

int main() {
  int dice_num;
  cin >> dice_num;

  vector<Dice> dices;
  dices.reserve(dice_num);
  for (auto i = 0; i < dice_num; i++) {
    Dice dice(inputDice());
    dices.push_back(dice);
  }

  bool is_diff_all = true;
  for (int i = 0; i < dice_num - 1 && is_diff_all; i++) {
    for (int j = i + 1; j < dice_num; j++) {
      if (dices.at(i).isEqual(dices.at(j))) {
        is_diff_all = false;
        break;
      }
    }
  }

  cout << (is_diff_all ? "Yes" : "No") << endl;
}

array<int, SURFACE_NUM> inputDice() {
  array<int, SURFACE_NUM> init;
  for (auto i = 0; i < SURFACE_NUM; i++) {
    cin >> init.at(i);
  }
  return init;
}