/*异常算术程序David Applegate(David(AT)research.att.com),2003年11月11日*************************************************************************描述Dismal算术是由Marc LeBrun于2003年发明的。下面是一个用于执行单调算术的C程序和令人沮丧的数字理论。无序加法和无序乘法的运算是在序列A087061(加法)和A087062(乘法)中描述在整数序列在线百科全书中。(A087062还有用于加法和乘法的Maple代码。)编译完这个C程序后,您可以输入令人沮丧的帮助它会回复用法:dismal cmd[args…]可用的cmd包括:div a b输出c,这样b*c=adivs a输出b,以便b*c=a用于某些c添加a b输出a+bmul a b输出a*bpcount a b计算[a,b]中的素数dinfo a输出有关除数的信息dinfo a b输出n的除数信息,a<=n<=bpdinfo a输出关于a的素数的信息pdinfo a b输出关于n的素数因子的信息,a<=n<=bhelp_dinfo描述dinfo和pdinfo的输出帮助输出此文本例如,令人沮丧的跳水10将以某种随机顺序产生10的所有黯淡除数:11020304050607080902456789(请注意,10只有一个令人沮丧的素数,即90!)**************************************************************************安装:调用这个文件dismal_eis.c并对其进行编译,例如使用cc-o拆卸_eis拆卸_eis.c***************************************************************************/#包括#包括#包括#包括#包括#包括typedef字符数字;#定义SWAP(a,b,t)((t)=(a),(a)=(b),(b)=(t))char*my_strdup(char*s){char*p=(char*)malloc((strlen(s)+1)*sizeof(char));如果(p==(char*)NULL){fprintf(stderr,“内存不足”);出口(1);}结构(p,s);返回p;}int isprime(无符号int p){无符号整数i;如果(p&1)==0),则返回0;对于(i=3;i*i<=p;i+=2){如果(p%i==0)返回0;}返回1;}无符号int nextprime(无符号int x){如果(x<3),返回3;x |=1;而(!i素数(x))x+=2;返回x;}typedef结构数字灰烬{无符号int大小;无符号int nelems;无符号int full;数字**表;}数字签名;#定义DIGITHASH_INITSIZE 1019#定义DIGITHASH_HIDENS 0.75#定义DIGITHASH_LODENS 0.35无效digitalhash_init(digitalhash*h){无符号整数i;h->大小=下一个素数(DIGITHASH_INITSIZE);h->nelems=0;h->full=(int)(DIGITHASH_HIDENS*h->size);h->表=(数字**)malloc(h->大小*sizeof(数字*));if(!h->表格){fprintf(stderr,“内存不足”);退出(1);}对于(i=0;i规模;i++)h->表格[i]=(数字*)NULL;}void digithash_free(digithash*h){无符号整数i;if(!h->表格)返回;对于(i=0;i规模;i++){如果(h->table[i])空闲(h->table[i);}自由(h->表格);}无符号int digithash_hash(数字*n){无符号整数v=0;而(*n)v=v*11+*n++;返回v;}int digithash_add_work(数字*h,数字*n,int add){无符号int loc=digithash_hash(n)%h->size;while(h->表格[loc]){if(!strcmp(h->table[loc],n))返回0;位置++;如果(loc>=h->尺寸)loc=0;}if(添加){h->表格[loc]=n;h->nelems++;}返回1;}void digithash_resize(数字灰烬*h){unsigned int newsize=nextprime((unsignedint)(h->nelems)/DIGITHASH_LODENS)+1);无符号int oldsize=h->size;数字**旧表=h->表;无符号整数i;h->表格=(数字**)malloc(新闻大小*sizeof(数字*));if(!h->表格){fprintf(stderr,“内存不足”);退出(1);}对于(i=0;i表[i]=(数字*)NULL;}h->尺寸=新闻尺寸;对于(i=0;ifull=(int)(DIGITHASH_HIDENS*h->大小);}int digithash_add(数字*h,数字*n){数字*ncopy=my_strdup(n);if(h->nelems>=h->满){数字大小(h);}if(数字添加工作(h,ncopy,1)){返回1;}其他{免费(ncopy);返回0;}}int digithash_find(数字*h,数字*n){返回!digithash_add_work(h,n,0);}int nfound=0;int ndeadend=0;int ndup=0;typedef结构dig_range{数字最小值;数字最大值;}数字范围;typedef结构div_num{整数长度;dig_range*digs;}div_num;typedef结构divide_help{div_numa;int编号;int*numorder;数字*res;数字洗牌;}divide_help;typedef结构堆栈元素{整数idx;数字d;}堆叠层;typedef结构堆栈{int顶部;int最大值;堆栈元素;}堆栈;#定义PUSH(s,id,dig){\如果(s)->顶部>=(s)->maxtop){\fprintf(stderr,“堆栈空间不足\n”)\退出(1)\} \(s) ->ents[(s)->顶部].idx=(id)\(s) ->ents[(s)->top].d=(dig)\(s) ->顶部++\}#定义POP(s,id,dig){\如果(s)->顶部<=0){\fprintf(stderr,“堆栈下溢\n”)\出口(1)\} \(s) ->顶部--\(id)=(s)->ents[(s)->top].idx\(dig)=(s)->ents[(s)->顶部].d\}typedef结构除数帮助{div_numa;编号b;int编号;int*numorder;数字*res;堆栈amaxstack;堆栈bmaxstack;数字洗牌;}除数帮助;typedef int(div_callback)(数字*,无效*);void create_stack(堆栈*s,int大小){s->ents=(stack_elem*)malloc(size*sizeof(stack_ elem));如果(!s->ents){fprintf(stderr,“内存不足”);出口(1);}s->maxtop=尺寸;s->顶部=0;}void free_stack(堆栈*s){自由(s->ents);s->最大值=0;s->顶部=0;}void demol_mul(数字*a,数字*b,数字*res){int reslen=字符串(a)+字符串(b)-1;整数i;整数j;对于(i=0;ires[i+j])res[i+j]=a[i];如果(b[j]<a[i]&b[j]>res[i+j])res[i>j]=b[j;}}}void demol_add(数字*a,数字*b,数字*res){int alen=字符串(a);int blen=字符串(b);while(*a&&alen>混合){*res++=*a++;alen--;}while(*b&&blen>alen){*res++=*b++;混合--;}同时(*a){如果(*a>*b)*res=*a;否则*res=*b;a++;b++;资源++;}*res=“\0”;}int spin(digit*res,div_num*n,digithash*resash,int深度,div_callback*回调,void*u_data){数字d;int nsol=0;if(深度>=n->len){res[depth]=“\0”;while(res[0]=='0')res++;if(digithash_add(resash,res)){nfound++;nsol=(*回调)(res,u_data);返回nsol;}其他{ndup++;返回0;}}对于(d=n->digs[depth].min;d<=n->digs[深度].max;d++){res[深度]=d;nsol+=自旋(res,n,resash,depth+1,callback,u_data);}返回nsol;}int divide_work(数字*num,数字*den,divide_help*h,int深度,div_callback*回调,void*u数据){整数i;整数j;int alen=h->a.len;内部omin;内瘤;int nsol=0;整数rval;int ncall=0;if(深度>=h->numlen){nsol=自旋(h->res,&h->a,&h->重新散列,0,回调,u_data);返回nsol;}i=h->numorder[深度];对于(j=(i>=alen?i alen+1:0);j<=i&&den[j];j++){如果(den[j]>num[i]&&h->a.digs[i-j].min<=num[i)&&h->a.digs[i-j].max>=数字[i]){omin=h->a.digs[i-j].min;omax=h->a.digs[i-j].max;h->a.digs[i-j].min=num[i];h->a.digs[i-j].max=num[i];ncall++;rval=divide_work(num,den,h,depth+1,回调,u_data);如果(rval<0)返回rval;nsol+=rval;h->a.digs[i-j].min=omin;h->a.digs[i-j].max=omax;}else if(den[j]==num[i]&&h->a.digs[i-j].max>=num[i]){omin=h->a.digs[i-j].min;如果(omin<num[i])h->a.digs[i-j].min=num[i];ncall++;rval=divide_work(num,den,h,depth+1,回调,u_data);如果(rval<0)返回rval;nsol+=rval;h->a.digs[i-j].min=omin;}}如果(ncall==0)ndeadend++;返回nsol;}void min_change(数字*num,整数numlen,div_num*a,整数j,div_num*b,堆栈*s){整数k;数字m=a->digs[j].min;对于(k=0;klen&&j+k<numlen;k++){如果(m>num[j+k]&&b->digs[k].max>num[j+k]){PUSH(s,k,b->digs[k].max);b->digs[k].max=num[j+k];}}}void unroll_stack(堆栈*s,int loc,div_num*a){整数i;数字d;而(s->顶部>位置){POP(s,i,d);a->digs[i].max=d;}}int divisor_work(数字*num,divisor_帮助*h,int深度,div_callback*回调,void*u_data){整数rval;整数rval2;整数i;整数j;int nsol=0;int ncall=0;整数omina;内瘤;内部ominb;int-omaxb;int-astackloc;int bstackloc;如果(深度>=h->numlen){rval=自旋(h->res,&h->a,&h->重新散列,0,回调,u_data);如果(rval<0)返回rval;rval2=自旋(h->res,&h->b,&h->重设,0,回调,u_data);如果(rval2<0)返回rval2;返回rval+rval2;}i=h->numorder[深度];对于(j=(i>=h->a.len?i-h->a.len+1:0);j<=i&&j<h->b.len;j++){如果(h->a.digs[i-j].max<num[i]|h->b.digs[j].mas<num[2])继续;如果(h->a.digs[i-j].min<=num[i]){omina=h->a.digs[i-j].min;omaxa=h->a.digs[i-j].max;ominb=h->b.digs[j].min;h->a.digs[i-j].min=num[i];h->a.digs[i-j].max=num[i];astackloc=h->amaxstack.top;bstackloc=h->bmaxstack.top;最小更改(num,h->numlen,&h->a,i-j,&h->b,&h-->bmaxstack);if(h->b.digs[j].min<num[i]){h->b.digs[j].min=num[i];最小更改(num,h->numlen,&h->b,j,&h->a,&h->amaxstack);}ncall++;rval=除数工作(num,h,depth+1,回调,u_data);如果(rval<0)返回rval;nsol+=rval;展开堆栈(&h->amaxstack,astackloc,&h->a);h->b.digs[j].min=ominb;展开堆栈(&h->bmaxstack,bstackloc,&h->b);h->a.digs[i-j].min=omina;h->a.digs[i-j].max=奥马哈;}if(h->b.digs[j].min<=num[i]){ominb=h->b.digs[j].min;omaxb=h->b.digs[j].max;omina=h->a.digs[i-j].min;h->b.digs[j].min=num[i];h->b.digs[j].max=num[i];astackloc=h->amaxstack.top;bstackloc=h->bmaxstack.top;最小更改(num,h->numlen,&h->b,j,&h->a,&h->amaxstack);if(h->a.digs[i-j].min<num[i]){h->a.digs[i-j].min=num[i];最小更改(num,h->numlen,&h->a,i-j,&h->b,&h-->bmaxstack);}ncall++;rval=除数工作(num,h,depth+1,回调,u_data);如果(rval<0),则返回rval;nsol+=rval;展开堆栈(&h->bmaxstack,bstackloc,&h->b);h->a.digs[i-j].min=omina;展开堆栈(&h->amaxstack,astackloc,&h->a);h->b.digs[j].min=ominb;h->b.digs[j].max=omaxb;}}如果(ncall==0)ndeadend++;返回nsol;}int dismal_divil(数字*num,数字*den,div_callback*回调,无效*u_data){int numlen=字符串(num);int reslen=numlen+1-strlen(den);divide_help h;整数i;整数j;整型*nmatch;整数*nloc;整数t;整数rval;if(reslen<=0){fprintf(stderr,“结果长度%d->无解决方案\n”,reslen);返回0;}h.res=(数字*)malloc((reslen+1)*sizeof(数字));如果(!h.res){fprintf(stderr,“内存不足”);出口(1);}对于(i=0;i<=reslen;i++){h.res[i]=“\0”;}h.a.len=reslen;h.numlen=数值;h.a.digs=(dig_range*)malloc(reslen*sizeof(dig_ range));h.numorder=(int*)malloc(numlen*sizeof(int));nmatch=(int*)malloc(numlen*sizeof(int));nloc=(int*)malloc(numlen*sizeof(int));if(!h.a.digs||!h.numorder||!nmatch||!nloc){fprintf(stderr,“内存不足”);出口(1);}对于(i=0;i=reslen?i-reslen+1:0);j<=i&&den[j];j++){if(den[j]>数[i]&&h.a.digs[i-j].max>num[i]){h.a.digs[i-j].max=num[i];}}}对于(i=0;i=reslen?i-reslen+1:0);j<=i&&den[j];j++){如果(den[j]>=num[i]&&h.a.digs[i-j].max>=num[i]){n匹配[i]++;}}}#如果为0printf(“结果数字最大值:”);对于(i=0;i=0; i——){对于(j=0;jn匹配[j+1]){SWAP(h.numorder[j],h.numoder[j+1],t);SWAP(n匹配[j],n匹配[j+1],t);}}}对于(i=0;inum=a;di->len=strlen(a);if(!strcmp(a,“8”)|!strcmp(a,“9”){di->is_prime=0;}其他{di->is_prime=1;}di->is_pseudoprime=1;di->ndivisors=0;di->nbounded_divisors=0;di->sum_divisors=0.0;di->sum_bounded_divisors=0.0;di->sum_bounded_divisors2=0.0;di->sum_ne_divitors=0.0;di->dismal_sum_divisors=(digit*)malloc((di->len+1)*sizeof(digit));di->dismal_sum_bounded_divisors=(数字*)malloc((di->len+1)*sizeof(数字));di->dismal_sum_bounded_divisors2=(数字*)malloc((di->len+1)*sizeof(数字));di->dismal_sum_ne_divitors=(digit*)malloc((di->len+1)*sizeof(digit));di->nprime_divisors=0;di->dismal_sum_prime_divisors=(digit*)malloc((di->len+1)*sizeof(digit));di->dismal_prod_prime_divisors=(digit*)malloc((DIV_prod_MUL*di->len+1)*sizeof(digit));di->sum_work=(digit*)malloc((DIV_PROD_MUL*di->len+1)*sizeof(digit));if(!di->dismal_sum_divisors ||!di->displa_sum_bounded_divisor||!di->dismal_sum_bounded_divisors2||!di->dismal_sum_ne除数||!di->dismal_sum_prime_divisors||!di->demal_prod_prime_divisors||!di->sum_work){fprintf(stderr,“内存不足”);出口(1);}di->dismal_sum_divisors[0]=“0”;di->dismal_sum_bounded_divisors[0]=“0”;di->dismal_sum_bounded_divisors2[0]=“0”;di->dismal_sum_ne_divitors[0]=“0”;di->dismal_sum_prime_divisors[0]=“0”;di->dismal_prod_prime_divisors[0]=“9”;di->sum_work[0]=“0”;di->dismal_sum_divisors[1]=“\0”;di->dismal_sum_bounded_divisors[1]=“\0”;di->dismal_sum_bounded_divisors2[1]=“\0”;di->dismal_sum_ne_divitors[1]=“\0”;di->dismal_sum_prime_divisors[1]=“\0”;di->dismal_prod_prime_divisors[1]=“\0”;di->sum_work[1]=“\0”;}无效free_div_inf(div_inf*di){自由(di->dismal_sum_divisors);自由(di->dismal_sum_bounded_divisors);自由(di->dismal_sum_bounded_divisors2);自由(di->dismal_sum_ne_divitors);自由(di->dismal_sum_prime_divisors);自由(di->demal_prod_prime_divisors);免费(di->sum_work);}div回调gather_inf;int gather_inf(数字*res,无效*u_data){div_inf*di=(div_info*)u_data;无符号int reslen=strlen(res);无符号int numlen=strlen(di->num);int numcmp=strcmp(res,di->num);双resf=atof(res);无符号整数i;if(numcmp&&strcmp(res,“9”)){di->is_prime=0;}如果(reslen>1&&reslen<numlen)di->is_pseudoprime=0;di->ndivisors++;demol_add(res,di->demol_sum_divisors,di->sum_work);strcpy(di->dismal_sum_divisors,di->sum_work);di->sum_divisors+=resf;if(reslen<numlen | | numcmp<=0){di->nboundd_divisors++;demol_add(res,di->demol_sum_bounded_divisors,di->sum_work);strcpy(di->dismal_sum_bounded_divisors,di->sum_work);di->sum_bounded_divisors+=resf;if(reslen<numlen | | numcmp<0){demol_add(res,di->demol_sum_bounded_divisors2,di->sum_work);strcpy(di->dismal_sum_bounded_divisors2,di->sum_work);di->sum_bounded_divisors2+=resf;}}if(numcmp!=0){demol_add(res,di->demol_sum_ne_diators,di->sum_work);strcpy(di->dismal_sum_ne_diviors,di->sum_work);di->sum_ne_divitors+=resf;}if(digithash_find(di->primehash,res)){di->nprime_divisors++;demol_add(res,di->demol_sum_prime_divisors,di->sum_work);strcpy(di->dismal_sum_prime_divisors,di->sum_work);if(reslen+strlen(di->dismal_prod_prime_divisors)<=DIV_prod_MUL*numlen){demol_mul(res,di->demol_prod_prime_divisors,di->sum_work);strcpy(di->demol_prod_prime_divisors,di->sum_work);}其他{对于(i=0;idemol_prod_prime_divisors[i]=“9”;di->dismal_prod_prime_divisors[DIV_prod_MUL*numlen]='\0';}}返回0;}div_callback proper_divisor;int属性除数(数字*res,无效*u_data){digit*num=(digit*)u_data;if(!strcmp(res,num)|!strcmp(res,“9”){返回0;}其他{返回1;}}无效incr_digit_num(数字*n){int i=字符串(n)-1;而(i>=0){如果(n[i]!=“9”){n[i]++;回报;}其他{n[i]=“0”;i——;}}n[0]=“1”;i=strlen(n);n[i]=“0”;n[i+1]=“\0”;回报;}void help_dinfo(void){printf(“dinfo和pdinfo输出一个标题行,然后为每个行输出一行”);printf(“请求的数字。每行由“|”分隔的字段组成。\n”);printf(“\n”);printf(“字段是:\n”);printf(“n数字\n”);printf(“如果n包含9,则为9ish 1,否则为0”);printf(“如果n是质数,则质数为1,否则为0”);printf(“n是素数,如果n!=9,如果n=a*b,\n”);printf(“则a==9或b==9\n”);printf(“如果n有长度在[2,n)中的除数,则为伪素数1”);printf(“divisors-除数的个数”);printf(“bd_divisors是[1,n]\n中n的除数”);printf(“dsum_divisors是n的除数的惨淡总和”);printf(“dsum_bd_diviators是[1,n]\n中n个除数的无意义和”);printf(“dsum_bd_divisors2是[1,n)中n个除数的糟糕和”);printf(“dsum_ne_diviators是n的除数之和!=n\n”);printf(“2*n糟糕的产品2*n\n”);printf(“sum_divisors是n的除数的正规和”);printf(“sum_bd_diviators是[1,n]\n中n个除数的正规和”);printf(“sum_bd_divisors2是[1,n)中n个除数的正规和”);printf(“sum_ne_divisors是n的除数的正常和!=n\n”);printf(“\n”);printf(“此外,pdinfo还包含以下关于素数除数的字段”);printf(“prime_divisors是n的素数除数”);printf(“sum_prime_divisors是n的素数除数之和”);printf(“prod_prime_divisors是n的素数除数的糟糕乘积”);printf(“因为像111…111这样的数字有很多”);printf(“素数,此乘积的上限为\n”);printf(“长度%d*长度(n)\n”,DIV_PROD_MUL);}void collect_primes(digithash*primehash,digit*hi,digit*x){无符号int hilen=strlen(hi);如果(!x){fprintf(stderr,“内存不足”);出口(1);}x[0]=“1”;x[1]=“\0”;while(strlen(x)<=希伦){if(strcmp(x,“8”)&&strcmp&&demol_diviators(x,proper_diviator,x)==0){digithash_add(素数哈希,x);}incr_digit_num(x);}}void dinfo_range(数字*lo,数字*hi,int primefield){digit*x=(digit*)malloc((strlen(hi)+2)*sizeof(digit));数字*x2=(数字*)malloc((strlen(hi)+2)*sizeof(digit));div_inf di;数字灰素数;如果(!x||!x2){fprintf(stderr,“内存不足”);出口(1);}digithash_init(&primehash);if(素数域){集合素数(&primehash,hi,x);}strcpy(x,lo);printf(“n|9ish|prime|pseudo-prime|divisors|bd_divisors|dsum_divisors| dsum_bd_ddivisors |dsum_bb_divisors 2|dsum_ne_divisors |2*n|sum_divisors|sum_bd_divisors2|sum_ne_difisors”);if(primefields)printf(“|prime_divisors|sum_prime_divisors|prod_prime_dviisors”);printf(“\n”);while(字符串(x)<字符串(hi)||(字符串(x)==字符串(hi)&&strcmp(x,hi)<=0)){init_div_inf(&di,x);di.primehash=primehash;demol_diviators(x,gather_inf,&di);demol_mul(x,“2”,x2);打印f(“%s|%d|%d|%d|%d |%d |%s |%s |%s|%s |%.0f|%.0f |%.0f”,x、 索引(x,'9')!=空,di.is_prime,di.is伪素数,di.ndivisors、di.nbounded_divisors、di.dismal_sum_divisor、,di.dismal_sum_bounded_divisors、di.discal_sum_bounded_dvisors2、,di.dismal_sum_ne_除数,x2,di.sum_divisors,di.sum_bounded_divisors、di.sum-bounded_divisors2、,di.sum_ne_divisors);if(素数域){printf(“|%d|%s|%s”,di.nprime_divisors,di.dismal_sum_prime_diviors,di.dempl_prod_prime_divisors);}printf(“\n”);free_div_inf(&di);incr_digit_num(x);}digithash_free(&primehash);自由(x2);自由(x);}无效pcount_range(数字*lo,数字*hi){digit*x=(digit*)malloc((strlen(hi)+2)*sizeof(digit));int pcount=0;无符号int output_length=strlen(lo);如果(!x){fprintf(stderr,“内存不足”);出口(1);}strcpy(x,lo);while(字符串(x)<字符串(hi)||(strlen(x)==strlen(hi)&&strcmp(x,hi)<=0)){if(strcmp(x,“8”)&&strcmp&&demol_diviators(x,proper_diviator,x)==0){pcount++;}incr_digit_num(x);if(字符串(x)>输出长度){printf(“%d个素数,位数<=%d”,pcount,output_length);fflush(标准输出);输出长度++;}}printf(“%d个素数在[%s,%s]\n”,pcount,lo,hi);自由(x);}int main(int ac,char**av){数字*res;如果(ac<2)使用(av[0]);if(!strcmp(av[1],“div”)&&ac==4){demol_divil(av[2],av[3],div_print,(void*)NULL);}else if(!strcmp(av[1],“divs”)&&ac==3){demol_diviators(av[2],div_print,(void*)NULL);}else if(!strcmp(av[1],“add”)&&ac==4){res=结果空间(av[2],av[3]);dismal_add(av[2],av[3],res);div_print(res,(void*)NULL);自由(res);}否则如果(!strcmp(av[1],“mul”)&&ac==4){res=结果空间(av[2],av[3]);demol_mul(av[2],av[3],res);div_print(res,(void*)NULL);自由(res);}else if(!strcmp(av[1],“dinfo”)&&ac==3){数据范围(av[2],av[2],0);}else if(!strcmp(av[1],“dinfo”)&&ac==4){数据范围(av[2],av[3],0);}else if(!strcmp(av[1],“pdinfo”)&&ac==3){数据范围(av[2],av[2],1);}else if(!strcmp(av[1],“pdinfo”)&&ac==4){数据范围(av[2],av[3],1);}else if(!strcmp(av[1],“pcount”)&&ac==4){pcount_range(平均值[2],平均值[3]);}否则if(!strcmp(av[1],“help_dinfo”)){帮助信息();}其他{用法(av[0]);}返回0;}