public List<EditOperation> calculatePath() {
    LinkedList<EditOperation> ops = new LinkedList<>();
    int i = seq1.length();
    int j = seq2.length();
    int dist = matrix[i][j];

    while (i > 0 && j > 0 && dist > 0) {
      int ins = matrix[i][j - 1];
      int del = matrix[i - 1][j];
      int sub = matrix[i - 1][j - 1];

      if (dist == ins + 1) {
        addOrUpdate(ops, INSERT, 1);
        j--;
      } else if (dist == del + 1) {
        addOrUpdate(ops, DELETE, 1);
        i--;
      } else {
        if (dist == sub) addOrUpdate(ops, SKIP, 1);
        else addOrUpdate(ops, SUBSTITUTE, 1);
        i--; j--;
      }

      dist = matrix[i][j];
    }

    if (i == 0) addOrUpdate(ops, INSERT, j);
    else if (j == 0) addOrUpdate(ops, DELETE, i);
    else addOrUpdate(ops, SKIP, i);

    return ops;
  }
Calculates Levenshtein distance and corresponding edit path between two character sequences.
Inspired from: https://etorreborre.blogspot.com/2008/06/edit-distance-in-scala_245.html

Ideas for improvements:
- Favor fewer EditOperationS when calculating distance and/or path
- Use algorithm with lower time and/or space complexity

@author Peter Niederwieser
spock-core/src/main/java/org/spockframework/runtime/condition/EditDistance.java