/* limited.c -- Compute T(s) from Project Euler Problem 256 Written November 9, 2019 by Eric Olson in K&R C for PDP-11 Less copying, more multiplication less division. Avoid computing T(s) when s doesn't have enough factors. */ #include #include /* #define smax 100000000l #define Pnum 1300 */ #define smax 100000000l #define Pnum 1300 #define fnum 10 typedef struct { long s; int fmax,i; long p[fnum]; char n[fnum]; } factors; static factors x; static int Pn,Tisn; static long P[Pnum],smin; static char z[fnum]; //#define void int static int tfree(k,l) long k,l; { long n=l/k; long lmin=(k+1)*n+2; long lmax=(k-1)*(n+1)-2; return lmin<=l && l<=lmax; } static long isprime(p) long p;{ int i; for(i=0;ismax/r+1) return; r*=P[i]; } printf("Distinct primes %d in factorisation too few!\n",fnum); exit(2); } static long ppow(p,n) long p; char n; { long r; if(!n) return 1; r=1; for(;;){ if(n&1) r*=p; n>>=1; if(!n) return r; p*=p; } } static long sigma(){ int i; long r=x.n[0]; for(i=1;i<=x.fmax;i++) r*=x.n[i]+1; return r; } static long T(){ int r,w; for(w=0;wx.fmax) break; k=1; l=1; for(i=0;i<=x.fmax;i++){ k*=ppow(x.p[i],z[i]); l*=ppow(x.p[i],x.n[i]-z[i]); } if(k<=l) r+=tfree(k,l); } return r; } static void Twork(){ int i,r; long s,fmax,pmax,p; s=x.s; r=sigma(); if(r>=Tisn){ r=T(); if(r==Tisn&&spmax) break; x.p[fmax]=p; x.s=s*p; x.i=i; x.fmax=fmax; Twork(); } x.n[fmax]=0; } static long Tinv(n) int n; { Tisn=n; x.p[0]=P[0]; x.n[0]=1; x.i=0; x.s=2; x.fmax=0; Twork(); return smin