1 3 1 6 7 3 8 5 2 4 6 2 7 5 4 8
is probably the lexicographically-least 8D answer.
Here are some solutions for various dimensions:
3: 2 3 1 2 1 3
4: 2 3 4 2 1 3 1 4
7: 1 4 1 5 6 7 4 2 3 5 2 6 3 7
8: 1 3 1 6 7 3 8 5 2 4 6 2 7 5 4 8
11: 1 2 1 4 2 8 9 10 4 11 6 3 7 5 8 3 9 6 10 5 7 11
12: 1 2 1 3 2 8 9 3 10 11 12 5 7 4 8 6 9 5 4 10 7 11 6 12
15: 1 2 1 3 2 4 10 3 11 12 4 9 14 15 13 7 8 10 5 6 11 9 12 7 5 8 6 14 13 15
16: 1 2 1 3 2 4 8 3 12 13 4 10 14 15 16 8 9 6 11 5 7 12 10 13 6 5 9 14 7 15 11 16
19: 1 2 1 3 2 4 5 3 9 15 4 14 5 13 16 17 18 19 9 10 7 12 6 8 11 15 14 13 7 6 10 16 8 17 12 18 11 19
20: 1 2 1 3 2 4 5 3 6 16 4 15 5 14 17 6 12 19 20 18 9 11 13 7 10 8 16 15 14 12 9 7 17 11 8 10 13 19 18 20
There appear to be 300 8D solutions. The reverse of a solution also is a solution. I found no solutions for n in the set {1, 2, 5, 6, 9, 10, 13, 14} and found solutions for n in {3, 4, 7, 8, 11, 12, 15, 16, 19, 20}, suggesting there are solutions only for n of the form 4k and 4k-1. (I didn't test at n=17 or 18 or n>20 as the program might take weeks to get done. First-solutions at n=19 and 20 took 20 minutes and 57 minutes to find.)
In a solution, let us write the occurrences of fruit i as i and i'. Fruits i and i' are not distinguishable, so we can arrange that i always appears before i'. Thus we can exhaust all possible orders of 2n items by generating and testing all permutations of n items, accepting those permutations such that an array of 2n cells
can be filled in via the following C code, with elements i and i' at distance i+1. For a given n-permutation, there is one way or no way to fill in the array of 2n cells.
void testPerm(int n) { // See if n-perm makes valid n-kabob
int minplace, i, j;
memset(dat, 0, sizeof(dat));
minplace = 1;
for (i=1; i<=n; ++i) {
j = pi[i];
while (dat[minplace])
++minplace; // Get to next available spot in dat
dat[minplace] = j;
if (minplace+j+1 > 2*n) return; // Fail if out of bounds
if (dat[minplace+j+1]) return; // Fail if already in use
dat[minplace+j+1] = j;
}
exitnow = 1;
showKebab(n);
}
Note, the above routine uses some globally-declared variables, as below. The current permutation is held in pi[1]...pi[n]
, and dat
is used in trying to generate an n-kabob from the n-permutation, or when printing a solution. Var exitnow
tells the caller whether to exit (eg, if a solution is found).
#define NMAX 21
int pi[NMAX+1], dat[2*NMAX+2];
int exitnow;
The routine that calls testPerm
is like the following, which implements a permutation algorithm of Dijkstra's.
void permuter(int n) {
int i, j, r, s, temp;
for (i=0; i <= n; i++) pi[i] = i; // Init to first perm, 1, 2...n
i = 1;
while (i && !exitnow) {
testPerm(n);
// Generate next permutation
i = n-1;
while (pi[i] > pi[i+1]) i--;
j = n;
while (pi[i] > pi[j]) j--;
temp = pi[i]; pi[i] = pi[j]; pi[j] = temp;
r = n; s = i+1;
while (r > s) {
temp = pi[r]; pi[r] = pi[s]; pi[s] = temp;
r--; s++;
}
}
}