Maximum number of 'moves' required to correctly rack pool balls (for 8 ball)? To correctly set up balls for 8-ball.
The balls must be arranged in a pattern like this:
    L
   H L
  L 8 H
 H L H L
L H L H H

Where:

*

*L are "the spots" numbered 1-7

*8 is the 8-ball

*H are "the stripes" numbered 9-15

There is a total of 12 valid set ups corresponding to 3 different 'symmetries?':

*

*rotating 60 degrees either way like:

    L          H
   H H        L H
  L L L      H H L
 H H 8 H    L 8 L H
H L H L L  L H L H L


*

*inversion by swapping Hs and Ls like:

    H
   L H
  H 8 L
 L H L H
H L H L L


*

*flipping across axis going through center of 8 ball and its nearest corner like:

    L
   L H
  H 8 L
 L H L H
H H L H L

A 'move' is swapping 2 balls.
What is then the maximum number of moves required to reach a correct set up from any set up?
 A: Well I turns out the answer is 4.
Since the maximum number of balls that can be in the wrong place is 8.
I brute forced solution by generating all 51480 permutations and compared each against the 12 solutions.
It would be trivial to find out distributions of distances to a solution, if anyone was interested.
Below is an example of a worst case scenario:
Nearest solution:
    L 
   H L 
  L 8 H 
 H L H L 
L H L H H 

Permutation:
    H 
   L H 
  8 L L 
 H L H L 
H L L H H 

Diff:
    H 
   L H 
  8 L L 
 . . . . 
H L . . . 

Below javacode (takes about 10 mins to run on a decent laptop):
import java.util.ArrayList;
import java.util.List;

public class Main {
    private static final int B = 0;
    private static final int L = 1;
    private static final int H = 2;
    public static void main(String[] args) {
        int[][] solutions = {
                {
                         L,
                        H,L,
                       L,B,H,
                      H,L,H,L,
                     L,H,L,H,H
                },
                {L, L, H, H, B, L, L, H, L, H, H, H, L, H, L}, 
                {H, L, H, H, B, L, L, H, L, H, H, L, H, L, L}, 
                {H, H, L, L, B, H, H, L, H, L, L, L, H, L, H}, 
                {L, H, H, L, L, L, H, H, B, H, H, L, H, L, L}, 
                {H, H, L, L, H, H, H, L, B, L, L, H, L, H, L}, 
                {H, L, L, H, H, H, L, L, B, L, L, H, L, H, H}, 
                {L, L, H, H, L, L, L, H, B, H, H, L, H, L, H}, 
                {H, L, H, H, H, L, L, B, L, H, L, H, L, H, L}, 
                {L, H, H, L, L, L, H, B, H, H, L, L, H, L, H}, 
                {L, H, L, L, L, H, H, B, H, L, H, L, H, L, H}, 
                {H, L, L, H, H, H, L, B, L, L, H, H, L, H, L}
        };

        final List<int[]> permutations = permutations(0, solutions[0]);
        int[][][] diffs = new int[permutations.size()][][];
        for (int i = 0; i < diffs.length; i++) {
            diffs[i] = diffs(permutations.get(i), solutions);
        }

        int[][] diffCounts = new int[diffs.length][];
        for (int i = 0; i < diffs.length; i++) {
            diffCounts[i] = diffCount(diffs[i]);
        }

        int[] minIndexes = new int[diffCounts.length];
        for (int i = 0; i < diffCounts.length; i++) {
            minIndexes[i] = indexOfMin(diffCounts[i]);
        }

        int[] mins = new int[minIndexes.length];
        for (int i = 0; i < mins.length; i++) {
            mins[i] = diffCounts[i][minIndexes[i]];
        }

        int indexOfMax = indexOfMax(mins);
        int max = diffCounts[indexOfMax][minIndexes[indexOfMax]];

        System.out.println("number of permutations:" + permutations.size());
        System.out.println("max of min diffs:" + max);
        System.out.println(permutationToString(solutions[minIndexes[indexOfMax]]));
        System.out.println(permutationToString(permutations.get(indexOfMax)));
        System.out.println(diffToString(diffs[indexOfMax][minIndexes[indexOfMax]], permutations.get(indexOfMax)));
    }

    private static int indexOfMax(int[] mins) {
        int maxIndex = 0;
        for (int i = 0; i < mins.length; i++) {
            if(mins[i] > mins[maxIndex]) {
                maxIndex = i;
            }
        }
        return maxIndex;
    }

    private static int[] diffCount(int[][] diffs) {
        int[] diffCount = new int[diffs.length];
        for (int j = 0; j < diffs.length; j++) {
            diffCount[j] = diffCount(diffs[j]);
        }
        return diffCount;
    }

    private static int[][] diffs(int[] test, int[][] solutions) {
        int[][] diffs = new int[solutions.length][];
        for (int i = 0; i < solutions.length; i++) {
            diffs[i] = sub(solutions[i], test);
        }
        return diffs;
    }

    private static int indexOfMin(int[] diffCounts) {
        int indexOfMin = 0;
        for (int j = 1; j < diffCounts.length; j++) {
            if(diffCounts[j] < diffCounts[indexOfMin]) {
                indexOfMin = j;
            }
        }
        return indexOfMin;
    }

    private static String toStringRaw(int[] test) {
        final StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < test.length; i++) {
            stringBuilder.append(i == 0 ? '{' : ',');
            stringBuilder.append(String.format("% d", test[i]));
        }
        stringBuilder.append('}');
        return stringBuilder.toString();
    }

    private static int diffCount(int[] ints) {
        int ret = 0;
        for (int i = 0; i < ints.length; i++) {
            if(ints[i] != 0) {
                ret++;
            }
        }
        return ret;
    }

    private static int[] sub(int[] ai0, int[] ai1) {
        int[] ret = new int[15];
        for (int i = 0; i < 15; i++) {
            ret[i] = ai0[i] - ai1[i];
        }
        return ret;
    }

    private static List<int[]> permutations(int offset, int[] ints) {
        final List<int[]> ret = new ArrayList<>();
        if(offset == ints.length - 1) {
            ret.add(ints);
        } else {
            List<int[]> p = permutations(offset + 1, ints);
            for (final int[] ints1 : p) {
                for (int i = offset; i < ints.length; i++) {
                    final int[] ints2 = swap(ints1, offset, i);
                    if(!contains(ret, ints2)) {
                        ret.add(ints2);
                    }
                }
            }
        }
        return ret;
    }

    private static boolean contains(List<int[]> list, int[] ints2) {
        boolean ret = false;
        for (int[] ints : list) {
            ret |= equals(ints, ints2);
        }
        return ret;
    }

    private static boolean equals(int[] ints, int[] ints2) {
        boolean ret;
        if(ints.length != ints2.length) {
            ret = false;
        } else {
            ret = true;
            for (int i = 0; (i <ints.length) && ret; i++) {
                ret &= ints[i] == ints2[i];
            }
        }
        return ret;
    }

    private static int[] swap(int[] ints, int i, int j) {
        int[] ints1 = new int[ints.length];
        System.arraycopy(ints, 0, ints1, 0, ints.length);
        ints1[i] = ints[j];
        ints1[j] = ints[i];
        return ints1;
    }

    private static String permutationToString(int[] ints) {
        char[] chars = {'8', 'L', 'H'};
        final StringBuilder sb = new StringBuilder();
        int i = 0;
        for(int j=1; j <= 5; j++) {
            for(int k=0; k < (5-j); k++) {
                sb.append(' ');
            }
            for(int k=0; k < j; k++) {
                sb.append(chars[ints[i]]);
                sb.append(' ');
                i++;
            }
            sb.append('\n');
        }
        return sb.toString();
    }

    private static String diffToString(int[] diff, int[] permutation) {
        char[] chars = {'8', 'L', 'H'};
        final StringBuilder sb = new StringBuilder();
        int i = 0;
        for(int j=1; j <= 5; j++) {
            for(int k=0; k < (5-j); k++) {
                sb.append(' ');
            }
            for(int k=0; k < j; k++) {
                sb.append(diff[i] != 0 ? chars[permutation[i]] : '.');
                sb.append(' ');
                i++;
            }
            sb.append('\n');
        }
        return sb.toString();
    }
}

```

