docs: function calculatePenalty(matrix) {
      var N = matrix.length;
      var penalty = 0;
      // Rule 1
      for (var i = 0; i < N; i++) {
          var pixel = matrix[i][0] & 1;
          var len = 1;
          for (var j = 1; j < N; j++) {
              var p = matrix[i][j] & 1;
              if (p == pixel) {
                  len++;
                  continue;
              }
              if (len >= 5) {
                  penalty += len - 2;
              }
              pixel = p;
              len = 1;
          }
          if (len >= 5) {
              penalty += len - 2;
          }
      }
      for (var j = 0; j < N; j++) {
          var pixel = matrix[0][j] & 1;
          var len = 1;
          for (var i = 1; i < N; i++) {
              var p = matrix[i][j] & 1;
              if (p == pixel) {
                  len++;
                  continue;
              }
              if (len >= 5) {
                  penalty += len - 2;
              }
              pixel = p;
              len = 1;
          }
          if (len >= 5) {
              penalty += len - 2;
          }
      }
  
      // Rule 2
      for (var i = 0; i < N - 1; i++) {
          for (var j = 0; j < N - 1; j++) {
              var s = matrix[i][j] + matrix[i][j + 1] + matrix[i + 1][j] + matrix[i + 1][j + 1] & 7;
              if (s == 0 || s == 4) {
                  penalty += 3;
              }
          }
      }
  
      // Rule 3
      function I(k) { return matrix[i][j + k] & 1 };
      function J(k) { return matrix[i + k][j] & 1 };
      for (var i = 0; i < N; i++) {
          for (var j = 0; j < N; j++) {
              if (j < N - 6 && I(0) && !I(1) && I(2) && I(3) && I(4) && !I(5) && I(6)) {
                  if (j >= 4 && !(I(-4) || I(-3) || I(-2) || I(-1))) {
                      penalty += 40;
                  }
                  if (j < N - 10 && !(I(7) || I(8) || I(9) || I(10))) {
                      penalty += 40;
                  }
              }
  
              if (i < N - 6 && J(0) && !J(1) && J(2) && J(3) && J(4) && !J(5) && J(6)) {
                  if (i >= 4 && !(J(-4) || J(-3) || J(-2) || J(-1))) {
                      penalty += 40;
                  }
                  if (i < N - 10 && !(J(7) || J(8) || J(9) || J(10))) {
                      penalty += 40;
                  }
              }
          }
      }
  
      // Rule 4
      var numDark = 0;
      for (var i = 0; i < N; i++) {
          for (var j = 0; j < N; j++) {
              if (matrix[i][j] & 1) numDark++;
          }
      }
      penalty += 10 * Math.floor(Math.abs(10 - 20 * numDark/(N * N)));
  
      return penalty;
  }