/* bc file squareroot2 */ /* min(x,y) */ define min(x,y){ if(yy) return(1) if(x==y) return(0) if(x0) return(1) if(a<0) return(-1) return(0) } define abs(n){ if(n>=0) return(n) return(-n) } define mod(a,b){ auto c c=a%b if(a>=0) return(c) if(c==0) return(0) return(c+b) } define mpower(a,b,c){ auto x,y,z x=a y=b z=1 while(y>0){ while(y%2==0){ y=y/2 x=(x*x)%c } y=y-1 z=mod(z*x,c) } return(z) } /* Shanks-Tonelli algorithm. * See "Square roots from 1; 24, 51, 10 to Dan Shanks", * Ezra Brown, The College Mathematics Journal, 30, No. 2, 82-95, 1999 */ define tonelli(a,p){ auto b,e,g,h,i,m,n,q,r,s,t,x,y,z q=p-1 t=mpower(a,q/2,p) if(t==q)return(0)/* a is a quadratic non-residue mod p */ s=q e=0 while(s%2==0){s=s/2;e=e+1} /* p-1=s*2^e */ x=mpower(a,(s+1)/2,p) b=mpower(a,s,p) if(b==1)return(x) for(n=2;n>=2;n++){ t=mpower(n,q/2,p) if(t==q) break } /* n is the least quadratic non-residue mod p */ g=mpower(n,s,p) r=e while(1){ y=b for(m=0;m<=r-1;m++){ if(y==1)break y=(y*y)%p } /*print "(m,x,b,g,r)=(",m,",",x,",",b,",",g,",",r,")\n"*/ /* ord_p(b)=2^m, m <= r-1, so m has decreased */ if(m==0)return(x) z=r-m-1 h=g for(i=0;i0){ "not soluble "; return(-1) } b=gcd1(m,n) y=n/a p=p/a x=mod(b*p,y) return(x) } define gcd1(m,n){ auto a,b,c,h,k,l,q,t if(n==0) return(sign(m)) a=m b=abs(n) c=mod(a,b) if(c==0) return(0) l=1 k=0 while(c>0){ q=(a-c)/b a=b b=c c=mod(a,b) h=l-q*k l=k k=h } return(k) } define gcd2(m,n){ auto a,b,c,h,k,l,q,t if(n==0) return(0) a=m b=abs(n) c=mod(a,b) if(c==0) return(sign(n)) l=0 k=1 while(c>0){ q=(a-c)/b a=b b=c c=mod(a,b) h=l-q*k l=k k=h } q=(a-c)/b if(n<0) return(-k) return(k) } define gcd(m,n){ auto a,b,c a=abs(m) /* a=r[0] */ if(n==0) return(a) b=abs(n) /* b=r[1] */ c=a%b /* c=r[2]=r[0] mod(r[1]) */ while(c>0){ a=b b=c c=a%b /* c=r[j]=r[j-2] mod(r[j-1]) */ } return(b) } /* inv(a,n) returns the inverse of a (mod n), n>0 if gcd(a,n)=1. * uses the fact that |s[j]|1){print "gcd(a,n)>1\n";return(0)} s=gcd1(a,n) if(s<0)return(s+n) return(s) } /* the bth power of a, where a is an integer, b a positive integer.*/ define exp(a,b){ auto x,y,z x=a y=b z=1 while(y>0){ while(y%2==0){ y=y/2 x=x*x } y=y-1 z=z*x } return(z) } pglobal[0]=2 pglobal[1]=3 pglobal[2]=5 pglobal[3]=7 pglobal[4]=11 pglobal[5]=13 pglobal[6]=17 pglobal[7]=19 pglobal[8]=23 pglobal[9]=29 pglobal[10]=31 pglobal[11]=37 pglobal[12]=41 pglobal[13]=43 pglobal[14]=47 pglobal[15]=53 pglobal[16]=59 pglobal[17]=61 pglobal[18]=67 pglobal[19]=71 pglobal[20]=73 pglobal[21]=79 pglobal[22]=83 pglobal[23]=89 pglobal[24]=97 pglobal[25]=101 pglobal[26]=103 pglobal[27]=107 pglobal[28]=109 pglobal[29]=113 pglobal[30]=127 pglobal[31]=131 pglobal[32]=137 pglobal[33]=139 pglobal[34]=149 pglobal[35]=151 pglobal[36]=157 pglobal[37]=163 pglobal[38]=167 pglobal[39]=173 pglobal[40]=179 pglobal[41]=181 pglobal[42]=191 pglobal[43]=193 pglobal[44]=197 pglobal[45]=199 pglobal[46]=211 pglobal[47]=223 pglobal[48]=227 pglobal[49]=229 pglobal[50]=233 pglobal[51]=239 pglobal[52]=241 pglobal[53]=251 pglobal[54]=257 pglobal[55]=263 pglobal[56]=269 pglobal[57]=271 pglobal[58]=277 pglobal[59]=281 pglobal[60]=283 pglobal[61]=293 pglobal[62]=307 pglobal[63]=311 pglobal[64]=313 pglobal[65]=317 pglobal[66]=331 pglobal[67]=337 pglobal[68]=347 pglobal[69]=349 pglobal[70]=353 pglobal[71]=359 pglobal[72]=367 pglobal[73]=373 pglobal[74]=379 pglobal[75]=383 pglobal[76]=389 pglobal[77]=397 pglobal[78]=401 pglobal[79]=409 pglobal[80]=419 pglobal[81]=421 pglobal[82]=431 pglobal[83]=433 pglobal[84]=439 pglobal[85]=443 pglobal[86]=449 pglobal[87]=457 pglobal[88]=461 pglobal[89]=463 pglobal[90]=467 pglobal[91]=479 pglobal[92]=487 pglobal[93]=491 pglobal[94]=499 pglobal[95]=503 pglobal[96]=509 pglobal[97]=521 pglobal[98]=523 pglobal[99]=541 pglobal[100]=547 pglobal[101]=557 pglobal[102]=563 pglobal[103]=569 pglobal[104]=571 pglobal[105]=577 pglobal[106]=587 pglobal[107]=593 pglobal[108]=599 pglobal[109]=601 pglobal[110]=607 pglobal[111]=613 pglobal[112]=617 pglobal[113]=619 pglobal[114]=631 pglobal[115]=641 pglobal[116]=643 pglobal[117]=647 pglobal[118]=653 pglobal[119]=659 pglobal[120]=661 pglobal[121]=673 pglobal[122]=677 pglobal[123]=683 pglobal[124]=691 pglobal[125]=701 pglobal[126]=709 pglobal[127]=719 pglobal[128]=727 pglobal[129]=733 pglobal[130]=739 pglobal[131]=743 pglobal[132]=751 pglobal[133]=757 pglobal[134]=761 pglobal[135]=769 pglobal[136]=773 pglobal[137]=787 pglobal[138]=797 pglobal[139]=809 pglobal[140]=811 pglobal[141]=821 pglobal[142]=823 pglobal[143]=827 pglobal[144]=829 pglobal[145]=839 pglobal[146]=853 pglobal[147]=857 pglobal[148]=859 pglobal[149]=863 pglobal[150]=877 pglobal[151]=881 pglobal[152]=883 pglobal[153]=887 pglobal[154]=907 pglobal[155]=911 pglobal[156]=919 pglobal[157]=929 pglobal[158]=937 pglobal[159]=941 pglobal[160]=947 pglobal[161]=953 pglobal[162]=967 pglobal[163]=971 pglobal[164]=977 pglobal[165]=983 pglobal[166]=991 pglobal[167]=997 /* * the Brent-Pollard method for returning a proper factor of a composite n. * See R. Brent, Bit 20, 176-184 */ define brent(n){ auto a,y,r,g,x,i,k,f a=1;y=0;r=1;g=1;prod=1 while(g==1){ x=y for(i=1;i<=r;i++)y=(y*y+a)%n k=0 f=0 while(f==0){ y=(y*y+a)%n k=k+1 z=abs(x-y) prod=prod*z if(k%10==0){ g=gcd(prod,n) prod=1 if (g>1)f=1 } if(k>=r)f=1 } r=2*r if(g==n || r == 16384){ g=1 r=1 y=0 a=a+1 if(a==5){ return(0) } } } return(g) } define pollard(n){ auto i,p,t,b b=t=2 p=1 for(i=2;i<=10^4;i++){ /*if(i%10==0){"i=";i}*/ t=mpower(t,i,n)/* now t=b ^(i!) */ p=gcd(n,t-1) if(p>1){ if(p 1,000,000, passes Miller's test * and is not divisible by pglobal[0],...,pglobal[167]. It is likely to be * prime. * primefactors(n) returns the number lglobal-t of q-prime factors of n. * rglobal[] and lglobal are global variables. * The prime and q-prime factors of n are qglobal[i],...,qglobal[jglobal-1] * with exponents * kglobal[i],...,kglobal[jglobal-1] where i is the value of the global * variable jglobal before primefactors(n) is called. */ define primefactors(n){ auto b,p,x,k,t b=1000 x=babydivide(n) t=lglobal while(x!=1){ k=0 p=v(x) while(x%p==0){ k=k+1 x=x/p } if(p>b*b){ rglobal[lglobal]=p lglobal=lglobal+1 } qglobal[jglobal]=p kglobal[jglobal]=k jglobal=jglobal+1 } return(lglobal-t) } /* * Selfridge's test for primality - see "Prime Numbers and Computer * Methods for Factorization" by H. Riesel, Theorem 4.4, p.106. * input: n (q-prime) * first finds the prime and q-prime factors of n-1. If no q-prime factor * is present and 1 is returned, then n is prime. However if at least one * q-prime is present and 1 is returned, then n retains "q-prime" status. * If 0 is returned, then either n or one of the q-prime factors of n-1 is * composite. */ define selfridge(n){ auto i,x,s,t,u i=jglobal u=primefactors(n-1) cglobal=u+cglobal /* cglobal,jglobal,lglobal are global variables. */ /* primefactors(n-1) returns jglobal-i primes and q-primes qglobal[i],...,qglobal[jglobal-1] */ /* and q-primes rglobal[l-u],...,rglobal[lglobal-1], where u>=0. */ while(i<=jglobal-1){ for(x=2;x0){ t=selfridge(rglobal[i]) if(t==0){ return(0) } i=i+1 cglobal=cglobal-1 } return(s) } /* the Chinese remainder theorem for the congruences x=a(mod m) * and x=b(mod n), m>0, n>0, a and b arbitrary integers. * The construction of O. Ore, American Mathematical Monthly, * vol.59,pp.365-370,1952, is implemented. * Same as chinese() in gcd, but with printing suppressed, except that -1 * is returned if there is no solution. */ define chinesee(a,b,m,n) { auto c,d,x,y,z d = gcd(m,n) if(mod(a-b,d)!=0){ return(-1) } x= m/d;y=n/d z=(m*n)/d c = mod(b*gcd1(x,y)*x + a*gcd2(x,y)*y,z) return(c) } define chineseae(a[],m[],n){ auto i,m,x m=m[0] x=a[0] for(i=1;i2, two solutions mod 2^(n-1):number=2,modulus=2^(n-1) * If p>2, two solutions mod p^n: number=2,modulus=p^n * If p divides a, there are two cases: * (i) p^n divides a, * (ii) p^n does not divide a. * In case (i) there are two cases: * (a) n=2m+1, (b) n=2m. * In case (a), the solution is x=0 (mod p^(m+1)): number=1, modulus=p^(m+1) * In case (b), the solution is x=0 (mod p^m): number=1, modulus=p^m * In case (ii) gcd(a,p^n)=p^r, r2 and A=1 (mod 8). * number=2, modulus=2^(n-m-1) */ define sqroot3(a,p,n){ auto aa,d,m,r,s,t,u,v d=a%p if(d){ if(p==2){ t=sqroot2(a,n) if(n==1 || n==2){ number=1 exponent=2 }else{ number=2 exponent=2^(n-1) } return(t) }else t=sqroot1(a,p,n) exponent=p^n number=2 return(t) }else{ u=p^n v=a%u if(v==0){ number=1 if(n%2==0){ exponent=p^(n/2) }else{ exponent=p^(1+n/2) } return(0) } r=0 aa=a v=aa%p while(v==0 && r<=n){ aa=aa/p v=aa%p r=r+1 } if(r%2){ return(-1) }else{ m=r/2 s=n-r if(p==2){ t=sqroot2(aa,s) if(s==1 || s==2){ exponent=2^(m+1) number=1 }else{ number=2 exponent=2^(n-m-1) } if(t==-1){ return(-1) }else{ return((2^m)*t) } }else{ t=sqroot1(aa,p,s) exponent=p^(n-m) number=2 if(t==-1){ return(-1) }else return((p^m)*t) } } } } define solution(){ auto i,j,x for(i=0; i1, we use the Chinese remainder theorem after solving mod * qglobal[i]^kglobal[i], i=0,...,e-1=omega(n)-1. * The array solution[0],...,solution[numbr-1] consists of the solutions * (mod n) in the range 0<=x<=n/2 and is used in cornacchia(). * numbr is a global variable. */ define sqroot(d,n,flag){ auto e,i,j,k,t,z globalsqcount=0 reduced_modulus=1 if(n==1){ reduced_solution[0]=0 numbr=1 solution[0]=0 if(flag){ print "Solution of x^2=",d,"(mod ",n,") is x=0 (mod 1)\n" print "The number of solutions (mod ",n,") is " } return(1) } numprimefactors=omega(n) for (i=0;ireduced_modulus){ reduced_solution[0]=reduced_modulus-soln[0] reduced_solution[1]=-reduced_solution[0] globalsqcount=2 } if(2*soln[0]=y. * Here a>0,b>0,m>a+b, gcd(a,b)=1=gcd(a,m). * If a=b=1, we get only solutions with 0m){ print "a+b>m\n" halt } temp=gcd(a,m) if(temp>1){ print "gcd(a,m)>1\n" halt } temp=gcd(a,b) if(temp>1){ print "gcd(a,b)>1\n" halt } a1=inv(a,m) a2=a1*(-b) ma=m/a mb=m/b n=sqroot(a2,m,0) print "Solving " if(a>1){ print a } print"x^2+" if(b>1){ print b } print "y^2=",m,":\n" if(n==0){ print "Number of primitive solutions=" return(0) } soln_number=0 count=0 for(i=0;i1){ r=mod(aa,bb) q1=aa/bb aa=bb bb=r qq= -q1 t2=tt+(qq*t1) tee2=rsv(t2*t2,mb) tt=t1 t1=t2 } } } if(a==1 && b==1){ print "Number of positive primitive solutions with y<=x is " }else{ print "Number of positive primitive solutions is " } print soln_number,"\n" return(soln_number) } /* Solving ax^2+bx+c=0 (mod n), where gcd(a,n)=1. * k=quadratic(a,b,c,n,flag) returns number k of solutions. * If k>0, we get a global array: * quadratic_solution[0],...,quadratic_solution[k-1]. * First solve t^2=b^2-4ac (mod 4n), -n0 && solution[i]=1,k-1>y>=1, of x^2+1=(k^2+1)(y^2+1) he says there exist r,s,a,b, 1<=r1){ temp=(k^2+1)/2 print "\n\t2a(x-yk)-r=",2*a[j]*(x-y*k)-r[i],",a/2=",a[j]/2 if(temp>x){ print ",x<(k^2+1)/2\n" }else{ print ",x>(k^2+1)/2!!!!\n" } }*/ globalb=b[j] return } } } } define testjprprint(x,y,k,flag){ auto count1, count2,i,j,r[],s[],a[],b[],xtemp,pmtemp count=0 count1=cornacchia0(1,1,k^2+1) for(i=0;im){ print "a+b>m\n" halt } temp=gcd(a,m) if(temp>1){ print "gcd(a,m)>1\n" halt } temp=gcd(a,b) if(temp>1){ print "gcd(a,b)>1\n" halt } a1=inv(a,m) a2=a1*(-b) ma=m/a mb=m/b n=sqroot(a2,m,0) /*print "Solving " if(a>1){ print a } print"x^2+" if(b>1){ print b } print "y^2=",m,":\n" if(n==0){ print "Number of primitive solutions=" return(0) }*/ soln_number=0 count=0 for(i=0;i1){ r=mod(aa,bb) q1=aa/bb aa=bb bb=r qq= -q1 t2=tt+(qq*t1) tee2=rsv(t2*t2,mb) tt=t1 t1=t2 } } } /*if(a==1 && b==1){ print "Number of positive primitive solutions with y<=x is " }else{ print "Number of positive primitive solutions is " }*/ /*print soln_number,"\n"*/ return(soln_number) } /* This returns the number of Type 1 exceptional solutions for the equation x^2+1=(k^2+1)(y^2+1). */ /* Dujella's conjecture implies that at most one can be met. */ define rs(k){ auto count,count1,s[],r[],i,x,y count1=0 count=cornacchia0(1,1,k^2+1) for(i=0;i1 && s[i]>1){ if((s[i]-1)%r[i]==0){ y=(s[i]-1)/r[i] x=r[i]+y*s[i] print "k=",k,",r[",i,"]=",r[i],",s[",i,"]=",s[i],",x=",x,",y=",y,",gcd(x,y)=",gcd(x,y),",e=1\n" count1=count1+1 if(y==2){ continue } } if((s[i]+1)%r[i]==0){ y=(s[i]+1)/r[i] x=r[i]+y*s[i] print "k=",k,",r[",i,"]=",r[i],",s[",i,"]=",s[i],",x=",x,",y=",y,",gcd(x,y)=",gcd(x,y),",e=-1\n" count1=count1+1 } } } return(count1) } /* this returns the number of Type 1 exceptional solutions in the range [m,n]. */ define rstest(m,n){ auto k,count,count1 count=0 for(k=m;k<=n;k++){ count1=rs(k) if(count1>1){ print "k=",k,",count1=",count1,">1\n" return }else{ if(count1==1){ count=count+1 }else{ /* print "k=",k,",count1=0\n"*/ } } } return(count) } /* This returns the number of Type 1 exceptional solutions for the equation x^2+1=(k^2+1)(y^2+1). */ /* Dujella's conjecture implies that at most one can be met. */ define rs0(k){ auto count,count1,s[],r[],i,x,y,u count1=0 count=cornacchia0(1,1,k^2+1) for(i=0;i1 && s[i]>1){ if((s[i]-1)%r[i]==0){ y=(s[i]-1)/r[i] x=r[i]+y*s[i] u=sqrt(r[i]) if(x%y){ print "(",u,",",k/u,",",s[i],",e=1)\n" } count1=count1+1 if(y==2){ continue } } if((s[i]+1)%r[i]==0){ y=(s[i]+1)/r[i] x=r[i]+y*s[i] u=sqrt(r[i]) if(x%y){ print "(",u,",",k/u,",",s[i],",e=-1)\n" } count1=count1+1 } } } return(count1) } /* this returns the number of Type 1 exceptional solutions in the range [m,n]. */ define rstest0(m,n){ auto k,count,count1 count=0 for(k=m;k<=n;k++){ count1=rs0(k) if(count1>1){ print "k=",k,",count1=",count1,">1\n" return }else{ if(count1==1){ count=count+1 } } } return(count) } /* This takes an integer which is expressible as the sum of two relatively prime squares n=r^2+s^2, r0){ i=i+1 s2=(-q)*s1+s0 s[i]=s2 t2=(-q)*t1+t0 t[i]=t2 a=b b=r r=a%b q=(a-r)/b qq[i]=q rr[i]=b s0=s1;s1=s2 t0=t1;t1=t2 } s2=(-q)*s1+s0 t2=(-q)*t1+t0 i=i+1 s[i]=s2 t[i]=t2 rr[i]=0 print "the Euclidean algorithm for m/n with m = ",m, " and n = ",n,"\n" l=i-1 if(flag){ for(j=0;j<=i;j++){ if(j>0 && j=1. See http://www.numbertheory.org/pdfs/hermite_serret.pdf */ define euclid1(n,x){ auto a,b,c,i,r,s,z,e,r0,r1,r2 z=sqrt(n) r0=n r1=x i=1 if(x<=z){ s=x r=r0%r1 a=(x*r-s)/n b=(r+s*x)/n print "(a,b,r,s)=(",a,",",b,",",r,",",s,")\n" print "x=ar+bs=",a*r+b*s,",br-as=",b*r-a*s,",",r,"^2+",s,"^2=",n,"\n" return(2) } r2=r0%r1 while(r2>0){ i=i+1 if(r2<=z){ s=r2 r=r1%r2 e=parity(i+1) a=(x*r-e*s)/n b=(r*e+s*x)/n print "(a,b,r,s)=(",a,",",b,",",r,",",s,")\n" print "x=ar+bs=",a*r+b*s,",br-as=",b*r-a*s,",",r,"^2+",s,"^2=",n,"\n" return(2*i) } r0=r1 r1=r2 r2=r0%r1 } } define squares1(n){ auto i,l r=sqroot(-1,n,1) print r,"\n" if(r==0){ print "no solution of x^2=-1 (mod n)\n" return } for(i=0;i