///VIRER /* * parallel ? * (abondance des composites dans crb) */ ///\VIRER /* * Questions or comments about this code : rao at labri dot fr */ #include "utils.hpp" #define Q_INF -1 #ifndef NODOUBLECHECK #define DOUBLECHECK #endif int nexteven(int a) { if(a<2) return 2; return a+(a&1); } int next1mod4(int a) { if(a>(1+(a/4*4))) return 5+(a/4*4); return 1+(a/4*4); } class gcdex_t { int i; }; /***** precomputation of small primes ******/ int B1=10000000; int B2=100001000; int B3=1000000; unsigned short *firstprimes; int *primes; int *rprimes; int nbrprimes; void initprimes() // precompute small primes { printf("B1= %Ld B2= %Ld\n",ll_t(B1),ll_t(B2)); int tt=1+B2/8; unsigned char *tmp=(unsigned char*)malloc(tt); for(int i=0;i>(i%8))&1) { for(long long j=i*i;j<=B2;j+=2*i) tmp[j/8]&=~(1<<(j%8)); } nbrprimes=0; for(long long i=2;i<=B2;i++) if((tmp[i/8]>>(i%8))&1) nbrprimes++; printf("%d primes <=B2\n",nbrprimes); primes=new int[nbrprimes]; int j=1;primes[0]=2; for(int i=3;i>(i%8))&1) { primes[j++]=i; } printf("init firstprimes OK\n"); firstprimes=new unsigned short[B1]; firstprimes[1]=0; for(int i=2;i>(i%8))&1) { firstprimes[i]=0; } else { int j; for(j=0;primes[j]*primes[j]<=i;j++) if(i%primes[j]==0) { firstprimes[i]=primes[j]; assert(primes[j]>1 && primes[j]>(i%8))&1) { rprimes[i]=k++; } } printf("init rprimes OK\n"); free(tmp); assert(j==nbrprimes); printf("initprimes OK\n"); } int nbrbaseisprime=5; bool isprimei(int a) { if(a >, int > mostwanted; ///\VIRER int_t assumedtrialcomp=int_t("100000000"); //option 'as'. (not checked with this program) list forceds; //forced paths ( 'fU' option ) list forceds_fail; int tabB[]={127,19,7,11,331,31,97,61,13,398581,1093,3,5,307,17,23,0}; int tabP[]={3,5,7,11,0}; //,13,17,0}; int tabP3[]={3,0}; int tabP19[]={3,5,7,11,13,17,19,0}; int tabC[]={0}; int *tab=tabB; int tabstar[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //tab for "special" branching int taballexact[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //tab for allexact branching int *tab_2=NULL; int sizetab=0; int sizetab_2=0; int tab2(int i) // tab2(i) return the ith prime number in the our modified order { if(i=nbrprimes) return 0; return primes[i+1]; } bool isbefore(const int_t &p, int j) //returns true if p is before tab2(i) in our order { if(j>sizetab_2) return p=primes[sizetab_2+1]) return false; for(int i=0;i10) {i= sizetab_2-10;printf("... ");} } printf("...\n"); for(int i=0;i10) {i= sizetab_2-10;printf("... ");} } printf("...\n"); #endif ///\VIRER } #define B_BIG 1 #define B_SMALL 2 #define B_SMALL1M3 4 #define B_NOCMP 16 #define C_PROD 64 #define C_NBRP 128 #define C_NBRDP 1024 #define C_COMP 256 #define C_COMPM2 2048 #define F_DEF (C_PROD+B_BIG) #define F_NBRP (C_NBRP+B_SMALL) #define F_COMP (C_COMP+B_BIG) #define F_COMPM2 (C_COMPM2+B_BIG) #define F_COMPF (C_COMP+B_BIG+B_NOCMP) #define F_FFF (C_PROD+B_BIG+B_NOCMP) #define F_NBRPF (C_NBRP+B_SMALL+B_NOCMP) #define F_NBRDP (C_NBRDP+B_SMALL) ///VIRER #define C_NBRPM2 512 #define F_NBRPM2 (C_NBRPM2+B_SMALL1M3) ///\VIRER int flags=F_DEF; struct exp_t { exp_t(int m=0) { minexp=m; exp=0; prime=true; maxexp=-1; nondiv=false; } bool prime; int minexp; int exp; int maxexp; bool nondiv; // if true, minexp+1 is not supposed to be a divisor of exp+1 int_t p; int q; bool special() const {return minexp%2;} bool br() const {return minexp!=0;} }; struct pfact_t{ pfact_t() {} pfact_t(int_t a) { fs[a]=exp_t(0); } map fs; void aff(ostream &o) const { for(map::const_iterator it=fs.begin();it!=fs.end();it++) { if(!it->second.prime) o<<"c"; o<first<<"^"<second.exp<<" "; } o<::const_iterator it=fs.begin();it!=fs.end();it++) r*=pow(it->first,it->second.exp); return r; } void aff2(ostream &o) const { for(map::const_iterator it=fs.begin();it!=fs.end();it++) { if(!it->second.prime) o<<"c"; o<first<<"^("<second.minexp; if(it->second.maxexp==it->second.minexp) o << "*"; if(it->second.nondiv && it->second.maxexp==-1) o << "°°"; o<<","<second.exp<<") "; if(!it->second.prime) o<<"["<second.p<<","<second.q<<"] "; } o<=0 && (fs[a].exp+e)>fs[a].maxexp) return false; fs[a].exp+=e; return true; } void addcomp(const int_t &a,const int_t &p,int q) { if(fs[a].exp) { cerr << " FATAL double comp "<< a << endl; aff2(cerr); abort(); } fs[a].exp+=1; fs[a].prime=false; fs[a].p=p; fs[a].q=q; } // return true if we have already supposed a special factor bool special() const { map::const_iterator it; for(it=fs.begin();it!=fs.end();it++) if(it->second.special()) return true; return false; } // check if gcd of every pair of factor is 1. just an assertion void assertgcd() const { map::const_iterator it,it2; for(it=fs.begin();it!=fs.end();it++) for(it2=fs.begin();it2!=it;++it2) { int_t g; mpz_gcd(g.get_mpz_t(),it->first.get_mpz_t(),it2->first.get_mpz_t()); if(g!=1) { cerr << "FATAL gcd = " << g << " : " << it->first << " " << it2->first << endl; aff2(cerr); { ofstream gcdout("gcdfacts.txt",ios_base::out|ios_base::app); #ifdef NOTH if(envprof) gcdout << "# " << envprof->indent() << endl; #endif if(!it->second.prime) gcdout <second.p<<" "<second.q+1 << " " << g << endl; if(!it2->second.prime) gcdout <second.p<<" "<second.q+1 << " " << g << endl; } throw gcdex_t(); //abort(); } } } ///VIRER #ifdef NOFACT ///\VIRER // add a list of factors with exponents. return false if this is impossible (in "special" branchings) bool add(const pfact_t &o) { map::const_iterator it; for(it=o.fs.begin();it!=o.fs.end();it++) { if(fs[it->first].maxexp>=0 && fs[it->first].exp+it->second.exp>fs[it->first].maxexp) return false; fs[it->first].exp+=it->second.exp; if(!it->second.prime) { fs[it->first].prime=false; fs[it->first].p=it->second.p; fs[it->first].q=it->second.q; } } #ifdef NOTH ///VIRER if(verb>=4) aff2(cout); #endif ///\VIRER assertgcd(); return true; } ///VIRER #else // add a list of factors with exponents. return false if this is impossible (in "special" branchings) bool add(const pfact_t &o) { bool cg=false; map::const_iterator it,it2; for(it=o.fs.begin();it!=o.fs.end();it++) { if(!cg) { if(!it->second.prime) { for(it2=fs.begin();it2!=fs.end();it2++) { if(it2->second.prime) continue; int_t g; mpz_gcd(g.get_mpz_t(),it->first.get_mpz_t(),it2->first.get_mpz_t()); if(g!=1) { cg=true;break; } } } else { for(it2=fs.begin();it2!=fs.end();it2++) { int_t g; mpz_gcd(g.get_mpz_t(),it->first.get_mpz_t(),it2->first.get_mpz_t()); if(g!=1) { cg=true;break; } } } } if(fs[it->first].maxexp>=0) { if(fs[it->first].exp+it->second.exp>fs[it->first].maxexp) return false; } fs[it->first].exp+=it->second.exp; if(!it->second.prime) { fs[it->first].prime=false; fs[it->first].p=it->second.p; fs[it->first].q=it->second.q; } } if(verb>=4) aff2(cout); if(!cg) return true; int_t r; if(0!=(r=checkgcd())) { gcd_error++; #ifdef DOUBLECHECK assert(isprime(r)); #endif if(verb>=2) aff2(cout); if(!split(r)) return false; if(verb>=2) aff2(cout); } return true; } bool split(const int_t &f) { #ifdef NOTH if(verb>=2) indcout()<<"split by "<1 && isprime(f)); #endif map::const_iterator it; for(it=fs.begin();it!=fs.end();++it) { if(it->second.prime) {continue;} if(isdiv(it->first,f)) { if(!addprime(f)) return false; int_t s=it->first/f; int_t c=it->first; int_t p=it->second.p; int q=it->second.q; #ifdef DOUBLECHECK assert(it->second.exp==1); #endif fs.erase(c); comperase(c); addfact(p,q,f); if(isprime(s)){ if(!addprime(s)) return false; } else addcomp(s,p,q); return true; } } return true; } // check if gcd of every pair of factor is 1. just an assertion int_t checkgcd(bool fatal=false) const { map::const_iterator it,it2; for(it=fs.begin();it!=fs.end();it++) for(it2=fs.begin();it2!=it;++it2) { int_t g; mpz_gcd(g.get_mpz_t(),it->first.get_mpz_t(),it2->first.get_mpz_t()); if(g!=1) { if(verb>=2) { cout << "gcd = " << g << " : " << it->first << " " << it2->first << endl; aff2(cout); } if(fatal) { cerr << "FATAL gcd != 1 " << endl; abort(); } return g; } } return 0; } #endif ///\VIRER /******* CHECKS **********/ int nbrdp() const { bool sp=special(); int r=0,exp; int_t mi=0; map::const_iterator it; if(sp==false) { //do something ? } for(it=fs.begin();it!=fs.end();it++) { if(it->first==2) continue; if(it->second.prime) { r++; } else { if(isperfectpower(it->first)) { cout << "FATAL: " << it->first << " is a perfect power (nbrdp)\n"; abort(); } r+=2; } } return r; } bool checkNBRDP() const { return nbrdp()::const_iterator it; if(sp==false) { for(it=fs.begin();it!=fs.end();it++) { #ifdef DOUBLECHECK assert(it->second.minexp%2==0); #endif if(it->second.prime==false || (it->first%4==1 && it->second.minexp==0)) { ////celui là peut etre impair r--;break; } //opt?: si composite, r-- et break aussi } //if(it==fs.end()) r++; // il faut un autre premier special } for(it=fs.begin();it!=fs.end();it++) { if(it->first==2) continue; if(it->second.prime) { if((it->second.minexp%2)==0) { exp=nexteven(it->second.exp); if(exp<2) exp=2; if(expsecond.minexp) exp=it->second.minexp; } else { #ifdef DOUBLECHECK assert((it->second.minexp%2)==1); //assert(it->second.exp<2); #endif exp=next1mod4(it->second.exp); if(expsecond.minexp) exp=it->second.minexp; } } else { if(isperfectpower(it->first)) { //if it is a perfect power, we cannot assume exp>=4 (but this is very improbable). cerr << "FATAL: " << it->first << " is a perfect power (nbrP)\n"; abort(); } exp=4; } r+=exp; } return r; } bool checkNBR() const { return nbrp()::const_iterator it; for(it=fs.begin();it!=fs.end();it++) { if(it->first==2) continue; if(it->second.prime) { r+=1; } else { if(isperfectpower(it->first)) { //if it is a perfect power, we cannot assume P>=2 (but this is very improbable). cerr << "FATAL: " << it->first << "is a perfect power\n"; abort(); } r+=2; } } return r; } bool checkNBRM2() const { return nbrp()-2*nbrP() ::const_iterator it; for(it=fs.begin();it!=fs.end();it++) { if(it->second.prime && it->first>2) { int exp=0; if(it->second.exp>it->second.minexp) { exp=it->second.exp; if(sp || it->first%4!=1) exp=nexteven(exp); else { if(nexteven(exp)second.minexp; //printf("e=%d m=%d (sp=%d) (mod=%d)-> %d\n",it->second.exp,it->second.minexp,sp,(it->first%4)==1?1:3,exp); assert(exp>0); if(pow(it->first,exp)>LIMIT) return false; } } return true; } bool checkCOMPM2() const { // marche pas avec 'all' bool sp=special(); map::const_iterator it; for(it=fs.begin();it!=fs.end();it++) { if(it->second.prime && it->first>2) { int exp=0; if(it->second.exp>it->second.minexp) { exp=it->second.exp; if(sp || it->first%4!=1) exp=nexteven(exp); else { if(nexteven(exp)second.minexp; //printf("e=%d m=%d (sp=%d) (mod=%d)-> %d\n",it->second.exp,it->second.minexp,sp,(it->first%4)==1?1:3,exp); assert(exp>0); if(exp>2 && pow(it->first,exp-2)>LIMIT) return false; } } return true; } /************** B ***************/ int_t B() const { // returns a lower bound for N ///VIRER //VERIF? ///\VIRER int_t r=1; int_t spp=1; int_t mdfsp=1,mdfnsp=1; #ifdef NOTH ///VIRER if(verb>=4) cout << "B: "; #endif ///\VIRER bool sp=special(); map::const_iterator it; for(it=fs.begin();it!=fs.end();it++) { if(it->first==2) continue; int exp=0; int expsp=0; int expnsp=0; if(it->second.prime) { assert(it->second.nondiv==0); if(it->second.minexp==0) { if(it->first%4==1) { expnsp=nexteven(it->second.exp); expsp=next1mod4(it->second.exp); } else { exp=nexteven(it->second.exp); } } else if(it->second.minexp%2==0) { exp=nexteven(it->second.exp); if(expsecond.minexp) exp=it->second.minexp; } else { // (it->second.minexp%2)==1 assert(sp); #ifdef DOUBLECHECK assert(it->second.minexp%4==1); assert(it->first%4==1); #endif exp=next1mod4(it->second.exp); if(expsecond.minexp) exp=it->second.minexp; } } else { expsp=expnsp=1; // le composite peut avoir des carrés... if(!(it->second.exp==1 && it->second.minexp==0)) cerr << "FATAL comp " << it->first << " minexp=" <second.minexp<< " exp=" << it->second.exp<second.exp==1 && it->second.minexp==0); #endif //if(expsecond.minexp) exp=it->second.minexp; } if(exp) { #ifdef NOTH ///VIRER if(verb>=4) cout << it->first << "^"<first,exp); ///VIRER } ///\VIRER } else { int_t tcsp=pow(it->first,expsp); int_t tcnsp=pow(it->first,expnsp); #ifdef NOTH ///VIRER if(verb>=4) cout << it->first << "^"<spp) { #ifdef NOTH ///VIRER if(nospecialinb && verb>=4) cout<<"'"; #endif ///\VIRER spp=tcnsp; } if(tcsp*mdfnsp=4) cout<<"*"; #endif ///\VIRER mdfsp=tcsp; mdfnsp=tcnsp; } r*=tcnsp; #ifdef NOTH ///VIRER if(verb>=4) cout<<" "; #endif ///\VIRER } } #ifdef NOTH ///VIRER if(verb>=4) cout<<"\n"; #endif ///\VIRER ///VIRER if(!nospecialinb) { ///\VIRER if(sp) { #ifdef NOTH ///VIRER if(verb>=4) cout << "ret= " << r <=4) cout << "ret(/)= " << r*mdfsp/mdfnsp <=mdfsp); return r*mdfsp/mdfnsp; ///VIRER } ///\VIRER ///VIRER if(nospecialinb) { if(sp) { #ifdef NOTH if(verb>=4) cout << "ret= " << r <=4) cout << "ret(/)= " << r/spp <::const_iterator it; mpq_class ab=1; for(it=fs.begin();it!=fs.end();it++) { if(it->first<=2 || !it->second.prime) continue; int exp=0; if(it->second.minexp) { if((it->second.minexp%2)==0) exp=nexteven(it->second.exp); else exp=next1mod4(it->second.exp); } else exp=nexteven(it->second.exp); if(expsecond.minexp) exp=it->second.minexp; ab*=sigma(it->first,exp); ab/=pow(it->first,exp); if(sp && ab>2) return ab; } if(sp) return ab; mpq_class abw=ab; for(it=fs.begin();it!=fs.end();it++) { if(it->first<=2 || false==it->second.prime || it->second.minexp!=0 || 1!=(it->first%4)) continue; int oexp=nexteven(it->second.exp); int nexp=next1mod4(it->second.exp); mpq_class ab2=ab; ab2/=sigma(it->first,oexp); ab2*=pow(it->first,oexp); ab2*=sigma(it->first,nexp); ab2/=pow(it->first,nexp); if(ab2::const_iterator it; r=1;rc=1; for(it=fs.begin();it!=fs.end();it++) { if(it->first>2) { if(it->second.prime) { mpq_class a; if(it->second.maxexp==-1) a=1+mpq_class(1)/(it->first-1); else a=mpq_class(sigma(it->first,it->second.maxexp))/pow(it->first,it->second.maxexp); r*=a; } else { ///VIRER // VERIFIER !!!!! ///\VIRER int_t l=1; int k=0; while(l<=it->first) {k++;l*=assumedtrialcomp;} mpq_class a=1+mpq_class(1)/assumedtrialcomp; for(;k>0;k--) rc*=a; } } } return r*rc; } bool checkAb() const { return compAb()<=2; } /****** BESTS *********/ void branchables(set &s) const { s.clear(); map::const_iterator it; for(it=fs.begin();it!=fs.end();it++) if(it->first!=2 && (!it->second.br()) && it->second.prime) s.insert(it->first); } void bests(list &s) const { set s2; branchables(s2); s.clear(); for(set::iterator it=s2.begin();it!=s2.end();++it) s.push_front(*it); } void bestssmalls(list &s) const { set s2; branchables(s2); s.clear(); for(set::iterator it=s2.begin();it!=s2.end();++it) s.push_back(*it); } void bestssmalls1m3(list &s) const { set s2; branchables(s2); s.clear(); for(set::iterator it=s2.begin();it!=s2.end();++it) if((*it%3)==1) s.push_back(*it); for(set::iterator it=s2.begin();it!=s2.end();++it) if((*it%3)!=1) s.push_back(*it); } }; ///VIRER string outrfactname=""; ///\VIRER string outrbcompname=""; string prefixname=""; ///VIRER #ifndef NOFACT #include "fact4.hpp" #else ///\VIRER void initoracle(int &ac, char **&av) { initprimes(); initlistfactors(); for(int i=1;iindent()); } int id; //thread id; // "tout" is the ostream where we write the tree. #ifndef NOTH ofstream tout; #else ostream &tout; #endif static string id2str(int id) { #ifndef NOTH char b[10]; snprintf(b,10,"%s%d_",prefixname.c_str(),id); return b; #else return prefixname; #endif } th_t(int i=0):id(i), #ifndef NOTH tout((id2str(i)+"log.txt").c_str(),ios_base::out|ios_base::app) #else tout(cout) #endif { stat_rec=0; envprof=NULL; outrbcomp=NULL; if(outrbcompname!="") { outrbcomp=new ofstream((id2str(i)+outrbcompname).c_str(),ios_base::out|ios_base::app); *outrbcomp<<"#"<LIMIT :\n"; return true; } if((flags & C_NBRP) &&!fsp.checkNBR()) { if(verb>=2) indcout()<< "NBRP>LIMIT :\n"; return true; } if((flags & C_NBRDP) &&!fsp.checkNBRDP()) { if(verb>=2) indcout()<< "NBRDP'>LIMIT :\n"; return true; } ///VIRER if((flags & C_NBRPM2) &&!fsp.checkNBRM2()) { if(verb>=2) indcout()<< "NBRPM2>LIMIT :\n"; return true; } ///\VIRER if((flags & C_COMP) &&!fsp.checkCOMP()) { if(verb>=2) indcout()<< "COMP>LIMIT\n"; return true; } if((flags & C_COMPM2) &&!fsp.checkCOMPM2()) { if(verb>=2) indcout()<< "COMPM2>LIMIT\n"; return true; } if(!fsp.checkAb()) { if(verb>=2) indcout()<< "Ab>2 :\n"; return true; } return false; } /* check for contracitions: previous + special banching and forb factors */ bool checkcontradiction2(pfact_t &fsp, const pfact_t &fs, const pfact_t &fa,ll_t borne) { fsp=fs; if(!fsp.add(fa)) { if(verb>=2) indcout()<< "contradiction add :\n"; return true; } if(checkcontradiction(fsp)) return true; bool skip=false; map::const_iterator it; for(it=fa.fs.begin();it!=fa.fs.end();it++) { if(it->second.prime && it->first>2 && isbefore(it->first,borne)) { if(fs.fs.find(it->first)!=fs.fs.end()) continue; // not a new prime factor if(verb>=2) indcout()<< it->first << " already eliminated:\n"; skip=true; break; } } if(skip) return true; return false; } path_t forced; //forced path ( 'U' option ) ofstream *outrbcomp; ///VIRER ofstream *outrfact; ///\VIRER ull_t stat_rec; int th_id; ///VIRER #ifdef NOFACT ///\VIRER // 'find' factors of f (factor if s(p^q)), and put the known decomposition into pfact int oraclefact(const int_t &p,int q,pfact_t &pfact,int_t &f) { path_t prof; if(envprof) prof=*envprof; facts_t *fa=getfacts(p,q); bool ok=0; facts_t::const_iterator it; for(it=fa->begin();it!=fa->end();++it) while(isdiv(f,*it)) { ///VIRER if(outrfact) *outrfact<=0 && prof.crb()>=maxcrb) { if(verb>=1) indcout() << "REC_RANGE FAIL MAXCRB\n"; envprof=oprof; return false; } mpq_class abw=fs.Ab(true); if(abw>=2) { if(verb>=1) indcout() << "REC_RANGE FAIL abw>=2\n"; envprof=oprof; return false; } int rlnbr=0; if(cond &C_NBRP) { rlnbr=LIMITNBRP-fs.nbrp(); rlnbr=(rlnbr+1)/2; } if(cond &C_NBRDP) rlnbr=LIMITNBRP-fs.nbrdp(); ll_t pom2; if(cond&C_NBRPM2) { ll_t t=LIMITNBRP; ll_t F=fs.nbrP(); /* 06/10/2012 > stop when (p/(p-1))^((7*t+31)/4-F) < 2/A Dans le papier, c'est un peu plus optimisé, on a: stop when (p/(p-1))^((7*t+14)/4-F) < 2/A Tu peux modifier le programme et mettre la borne du papier ? */ //pom2=((7*t+31)/4-F); pom2=((7*t+17)/4-F); if(verb>=2) { mpq_class b=abw; indcout() << " t=" << t << " F="< pmax and not in S\n"; if(i>sizetab_2) break; continue; } if(i=3) indcout()<< p << " already eliminated\n"; continue; } map::const_iterator it=fs.fs.find(pt); if(it!=fs.fs.end() && it->second.minexp) { if(verb>=2) indcout() << "already "<< p<=borne); pfact_t fs2=fs; path_t prof2=prof; prof2.add(-1); bool r=rec(fs2,pt,prof2,i); if(!r) rok=false; } } if(p==0) { if(verb>=1) indcout() << "REC_RANGE FAIL p limit (max = "<< pm<<" )" << endl; rok=false; } if(verb>=1) indcout() << "\\REC_RANGE " << rok << " N="<< prof.crb() << " size=" << stat_rec-str<=profmax) return false; int forcedq=-1; if(forced.h()>prof.h()) { if(!forced.compat(prof,p)) { //indcout()<< "wrong forced path !!!\n"; return true; } list >::const_iterator it1=forced.p.begin(),it2=prof.p.begin(); while(true) { if(it1==forced.p.end() || it2==prof.p.end()) break; it1++;it2++; } assert(it1!=forced.p.end()); forcedq=it1->second; } if(prof.h()pow(int_t(10),LIMEXPNBRDP)) { last=true; fs.fs[p].minexp=q; fs.fs[p].maxexp=Q_INF; } else { fs.fs[p].minexp=q; fs.fs[p].maxexp=q; } } else { int allexact=false; if(p=0) { if(qforcedq) break; } #if 0 if(!forced.compat(prof,p,q)) { //for 'U' option /* contradictions */ if(q>=2 && checkcontradiction(fs)) { tout<<"break without process full path...\n"; break; } continue; } #endif if(verb>=2) indcout()<<"~ "<< p << " " << q <=0 && fs.fs[p].exp>fs.fs[p].maxexp) { if(verb>=2) indcout()<<" exp>max"<=2) break; continue; } if(fs.fs[p].nondiv==0 || fs.fs[p].minexp==fs.fs[p].maxexp) { int_t bs=sigma(p,q); int_t b; if(verb>=3) { indcout()<<"current: ";fs.aff2(tout); indcout()<<"s("<-2;ii++) { b=bs; fa=pfact_t(); rf=tryfactorize(p,q,fa,b,tr[ii]); #ifdef DOUBLECHECK if(fa.prod()!=bs) { cerr << "assert prod error: "<=3) indcout()<<"cannot fact "<

lb; if(flags&B_BIG) fsp.bests(lb); else if(flags&B_SMALL) fsp.bestssmalls(lb); else if(flags&B_SMALL1M3) fsp.bestssmalls1m3(lb); else abort(); ///VIRER #ifndef NOFACT /* if no factor, 'lastchance' factoring... */ if(!lb.size()) { if(verb>=1) { indcout()<< "cannot branch : "; // << endl; fsp.aff2(tout); indcout()<< "try fact"<< endl; } if(tryfactorize(fsp)) { if(verb>=1) indcout()<< " OK no RB\n"; if(flags&B_BIG) fsp.bests(lb); else if(flags&B_SMALL) fsp.bestssmalls(lb); else if(flags&B_SMALL1M3) fsp.bestssmalls1m3(lb); else abort(); } } #endif ///\VIRER if(outrbcomp && !lb.size()) for(map::const_iterator it=fsp.fs.begin();it!=fsp.fs.end();it++) { if(it->second.prime) continue; (*outrbcomp)<second.p<<" "<second.q<<" "<first<=1) { indcout()<< "no branch ! : "; // << endl; fsp.aff2(tout); } { //aff mpq_class ab=fsp.Ab(),abw=fsp.Ab(true); double fl=ab.get_d(),flw=abw.get_d(); if(verb>=1) indcout() << "Ab= " << fl << " Abw=" << flw << endl; } if(flags & C_NBRP) { { //aff mpq_class ab=fsp.Ab(),abw=fsp.Ab(true); double fl=ab.get_d(),flw=abw.get_d(); int re=LIMITNBRP-fsp.nbrp(); int np=(re+1)/2; assert(np>0); double lala=2/fl; double lim=pow(lala,1./np); assert(lim>1.); double lp=1./(lim-1.); if(verb>=1) indcout() << "P max: " << lp << endl; if(flw<2) { double lala=2/flw; double lim=pow(lala,1./np); assert(lim>1.); double lp=1./(lim-1.); if(verb>=1) indcout() << "P max w: " << lp << endl; } } // CRB: path_t p2=prof; p2.add(p,q); r=rec_range(fsp,C_NBRP,p2,borne); if(r==false) ok=false; if(forced.h()>= p2.h()) break; } else if(flags & C_NBRPM2) { // CRB: path_t p2=prof; p2.add(p,q); r=rec_range(fsp,C_NBRPM2,p2,borne); if(r==false) ok=false; if(forced.h()>= p2.h()) break; } else if(flags & C_PROD) { // CRB: path_t p2=prof; p2.add(p,q); r=rec_range(fsp,C_PROD,p2,borne); if(r==false) ok=false; if(forced.h()>= p2.h()) break; } else if(flags & C_NBRDP) { path_t p2=prof; p2.add(p,q); r=rec_range(fsp,C_NBRDP,p2,borne); if(r==false) ok=false; if(forced.h()>= p2.h()) break; } else { //CBR not handled if(verb>=0) indcout()<< " RB !!!\n"; abort(); path_t p2=prof; p2.add(p,q); ok=false; if(forced.h()>= p2.h()) break; } ///VIRER int mwsize=stat_rec-mwosize; #ifdef MOSTWANTED for(map::const_iterator it=fsp.fs.begin();it!=fsp.fs.end();it++) { if(it->second.prime) continue; pair > x=make_pair(it->first,make_pair(it->second.p,it->second.q)); mostwanted[x]+=mwsize; } #endif ///\VIRER continue; } /* if factor(s), branch on the "best" prime */ list::const_iterator it=lb.begin(); path_t p2=prof; p2.add(p,q); if(!rec(fsp,*it,p2,borne)) ok=false; if(forced.h()>= p2.h()) break; } else { //NBRDP pfact_t fsp; fsp=fs; if(verb>=3) { indcout()<<"current: ";fs.aff2(tout); indcout()<="< lb; if(flags&B_BIG) fsp.bests(lb); else if(flags&B_SMALL) fsp.bestssmalls(lb); else abort(); if(outrbcomp && !lb.size()) for(map::const_iterator it=fsp.fs.begin();it!=fsp.fs.end();it++) { if(it->second.prime) continue; (*outrbcomp)<second.p<<" "<second.q<<" "<first<=1) { indcout()<< "no branch ! : "; // << endl; fsp.aff2(tout); } { //aff mpq_class ab=fsp.Ab(),abw=fsp.Ab(true); double fl=ab.get_d(),flw=abw.get_d(); if(verb>=1) indcout() << "Ab= " << fl << " Abw=" << flw << endl; } if(flags & C_NBRDP) { path_t p2=prof; p2.add(p,q); r=rec_range(fsp,C_NBRDP,p2,borne); if(r==false) ok=false; if(forced.h()>= p2.h()) break; } else { //CBR not handled if(verb>=0) indcout()<< " RB !!!\n"; abort(); path_t p2=prof; p2.add(p,q); ok=false; if(forced.h()>= p2.h()) break; } continue; } /* if factor(s), branch on the "best" prime */ list::const_iterator it=lb.begin(); path_t p2=prof; p2.add(p,q); if(!rec(fsp,*it,p2,borne)) ok=false; } } } catch(gcdex_t e) { indcout()<< "GCD error..."<=2) indcout()<<"end " << p << " " << q << endl; envprof=oprof; if(prof.h()first); after=0; } for(int mit=0;upto || tab[mit] ;mit++) { int i=tab2(mit); ///VIRER #if 0 if(!i) { static int io=tab2(nbrprimes-2); io++; while(!isprime(io)) io++; i=io; } #endif ///\VIRER assert(i>2); if(upto && i>upto) break; if(uniq && i!=uniq) continue; if(after) uniq=0; #ifdef NOTH if(mit<100 || mit%5000==0) fprintf(stderr,"i=%d \r",tab2(mit)); #endif path_t p; pfact_t pf = pfact_t(int_t(i)); ll_t osr=stat_rec; bool rr=rec(pf,i,p,mit); if(!rr) ret=0; tout << "\n--- RETURN FOR " << i; if(forced.h()) {tout<<" / "; forced.aff(tout);} tout<< " : " << rr<< " (ar : " << ret << " size= " <2); if(thupto && p>thupto) ip=-1; } if(ip>=0) thmit++; else end=true; } pthread_mutex_unlock(&mutex); if(end) break; int rr=(thmode ? th.main_proc_uniq(ip) : th.main_proc(f)); if(!rr) { ret=0; pthread_mutex_lock(&mutex); forceds_fail.push_back(f); pthread_mutex_unlock(&mutex); } } printf("END THREAD %d RET=%d\n",id,ret);fflush(stdout); return NULL; } #endif int main(int ac, char **av) { path_t forced; int uniq=0,after=0; int nbrthreads=1; ///VIRER int retry=0; ///\VIRER { strcpy(cmdline,""); for(int i=0;i log.log &\n",cmdline); } ///VIRER cout<< "define: "; #ifdef DOUBLECHECK cout << "DOUBLECHECK "; #endif cout<1 && av[1][0]=='-') { if(!strcmp(av[1]+1,"v")) {verb++;ac-=1;av+=1;continue;} if(!strcmp(av[1]+1,"q")) {verb--;ac-=1;av+=1;continue;} if(!strcmp(av[1]+1,"SIZE")) {BE=atoi(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"NBRP")) { tab=tabP; flags=F_NBRP; LIMITNBRP=atoi(av[2]); assert(LIMITNBRP%2); ac-=2;av+=2; continue; } if(!strcmp(av[1]+1,"NBRDP")) { tab=tabP3; flags=F_NBRDP; LIMITNBRP=atoi(av[2]); if(av[1][2]=='F') {assert(0); /*flags=F_NBRPF;*/} ac-=2;av+=2;continue; } if(!strcmp(av[1]+1,"ED")) {LIMEXPNBRDP=atoi(av[2]);ac-=2;av+=2;continue;} ///VIRER if(!strcmp(av[1]+1,"NBRPM2")) { tab=tabP19; flags=F_NBRPM2; LIMITNBRP=atoi(av[2]); assert(LIMITNBRP%2); ac-=2;av+=2; continue; } ///\VIRER if(!strcmp(av[1]+1,"COMP")) { tab=tabC; flags=F_COMP; BE=atoi(av[2]); ac-=2;av+=2;continue; } if(!strcmp(av[1]+1,"COMPM2")) { tab=tabC; flags=F_COMPM2; BE=atoi(av[2]); ac-=2;av+=2;continue; } if(!strcmp(av[1]+1,"u")) {uniq=atoi(av[2]); ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"a")) {uniq=atoi(av[2]); after=1;ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"U")) { int_t p=int_t(av[2]); int q=atoi(av[3]); forced.add(p,q); av+=3;ac-=3; continue; } if(!strcmp(av[1]+1,"pm")) {profmax=atoi(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"lm")) {limsize=atoi(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"t")) {nbrthreads=atoi(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"as")) {assumedtrialcomp=int_t(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"fileprefix")) {prefixname=(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"fU")) { FILE *in=fopen(av[2],"rt"); assert(in); char bf[100000]; while(fgets(bf,100000,in)) { assert(strlen(bf)<99900); if(bf[0]=='#' || bf[0]==0 || bf[0]=='\n') continue; forceds.push_back(path_t(bf)); } fclose(in); av+=2;ac-=2; continue; } if(!strcmp(av[1]+1,"F")) {addflags|=B_NOCMP;ac-=1;av+=1;continue;} ///VIRER if(!strcmp(av[1]+1,"retry")) {retry++;ac-=1;av+=1;continue;} ///\VIRER if(!strcmp(av[1]+1,"crb")) {maxcrb=atoi(av[2]);ac-=2;av+=2;continue;} if(!strcmp(av[1]+1,"ut")) { double lala=atoi(av[2]); upto=pow(10.,lala); printf("upto %d\n",upto); ac-=2;av+=2;continue; } if(!strcmp(av[1]+1,"UT")) { upto=atoll(av[2]); printf("upto %d\n",upto); ac-=2;av+=2;continue; } if(!strncmp(av[1]+1,"X",1)) { int k=atoi(av[1]+2); int i=atoi(av[2]); assert(k==2 || k==4); assert(i forceds_copy; if(retry==2) forceds_copy=forceds; ///\VIRER printf("forceds.size= %d\n",int(forceds.size())); #ifdef NOTH if(forceds.empty()) forceds.push_back(path_t()); printf("START\n"); fprintf(stderr,"START \r"); { th_t th; for(list::iterator it=forceds.begin();it!=forceds.end();++it) th.main_proc(*it,uniq,after); } #else if(forceds.empty()) { thmode=1; assert(!uniq || after); if(uniq) { for(thmit=0;tab2(thmit) && tab2(thmit)!=uniq;thmit++); assert(tab2(thmit)); } if(upto) thupto=upto; } printf("START\n");fprintf(stderr,"START \r"); if(nbrthreads<=1) { int zero=0; thread_main(&zero); } else { int tid[nbrthreads]; for(int i=0;i::iterator it=forceds.begin();it!=forceds.end();++it) { it->aff(cout);cout< >,int >::iterator it; map > > > mwback; map > > >::iterator it2; for(it=mostwanted.begin();it!=mostwanted.end();it++) mwback[it->second].push_back(it->first); for(it2=mwback.begin();it2!=mwback.end();++it2) for(list > >::iterator it3=it2->second.begin();it3!=it2->second.end();it3++) mwout<second.first<<" " <second.second<<" "<first<<" " <first<