@@ -586,10 +586,11 @@ int64_t tfac (int64_t N, int64_t t, int fast, int feasible, int verbosity, int v
586
586
}
587
587
588
588
589
- // returns a value of t >= N/3 that yields a good lower bound on t(N), or 0 if no such t can be found
590
- int64_t tbound (int64_t N , int fast , int exhaustive , int verbosity , int verify )
589
+ // returns a value of t >= aN/b that yields a good lower bound on t(N), or 0 if no such t can be found
590
+ int64_t tbound (int64_t N , int a , int b , int fast , int exhaustive , int verbosity , int verify )
591
591
{
592
- int64_t t = cdiv (N ,3 );
592
+ assert (a * 5 <= 2 * b && a * 4 >= b );
593
+ int64_t t = cdiv (a * N ,b );
593
594
int64_t cnt = tfac (N ,t ,fast ,0 ,verbosity ,verify ,0 );
594
595
while ( cnt < N ) cnt = tfac (N ,-- t ,fast ,0 ,verbosity ,verify ,0 );
595
596
int64_t tmin = t , tmax = (2 * N )/5 ;
@@ -645,7 +646,7 @@ int64_t tbound (int64_t N, int fast, int exhaustive, int verbosity, int verify)
645
646
static void usage (void )
646
647
{
647
648
fprintf (stderr ,
648
- "Usage: egs [-v level] [-h filename] [-d filename] [-r] [-c] [-e] [-f] N-range [t]\n"
649
+ "Usage: egs [-v level] [-h filename] [-d filename] [-r] [-c] [-e] [-f] N-range [t or t/N ratio ]\n"
649
650
" -v level integer verbosity level -1 to 4 (optional, default is 0)\n"
650
651
" -h filename hint-file with records N:t (required if range of N is specified)\n"
651
652
" -d filename output-file to dump factorization to (one factor per line, only valid if t is specified)\n"
@@ -655,7 +656,8 @@ static void usage (void)
655
656
" -f use fast version of greedy algorithm\n"
656
657
" -m exponent for primecount/primesieve cutuff, must lie in [1/6,1/3]\n"
657
658
" N-range integer N or range of integers minN-maxN (required, scientific notation supported)\n"
658
- " t integer t to use for single N (optional, a good t will be determined if unspecified)\n" );
659
+ " t integer t to use for single N (optional, a good t will be determined if unspecified)\n"
660
+ " t/N ratio a/b with integers a,b>0 specifying t = ceil(aN/b), set to 1/3 if unspecified\n" );
659
661
660
662
}
661
663
@@ -666,10 +668,11 @@ int main (int argc, char *argv[])
666
668
int verbosity = 0 , exhaustive = 0 , create = 0 , fast = 0 , verify = 0 ;
667
669
char * hintfile = 0 , * dumpfile = 0 ;
668
670
int64_t minN = 0 , maxN = 0 , t = 0 ;
671
+ int a = 1 , b = 3 ;
669
672
670
673
for ( int i = 1 ; i < argc ; i ++ ) {
671
674
char * s = argv [i ];
672
- if ( maxN > minN || t ) { fprintf (stderr , "ignoring extraneous argument %s\n" ,s ); continue ; }
675
+ if ( maxN > minN && t ) { fprintf (stderr , "ignoring extraneous argument %s\n" ,s ); continue ; }
673
676
if ( * s == '-' ) {
674
677
switch (* (s + 1 )) {
675
678
case 'v' : { if ( i + 1 >= argc ) { usage (); return -1 ; } verbosity = atoi (argv [i + 1 ]); i ++ ; break ; }
@@ -698,7 +701,14 @@ int main (int argc, char *argv[])
698
701
maxN = minN ;
699
702
}
700
703
} else {
701
- t = strtold (s ,0 );
704
+ char * x ;
705
+ if ( (x = strchr (s ,'/' )) ) {
706
+ a = atoi (s ); b = atoi (x + 1 );
707
+ assert (a > 0 && b > 0 && 4 * a >= b && 5 * a <= 2 * b );
708
+ } else {
709
+ if ( maxN > minN && t ) { fprintf (stderr , "For a range of N you need to specify the t/N ratio (e.g. 1/3) not a fixed value of t\n" ); return -1 ; }
710
+ t = strtold (s ,0 );
711
+ }
702
712
}
703
713
}
704
714
}
@@ -720,6 +730,9 @@ int main (int argc, char *argv[])
720
730
setup (maxp ,maxm );
721
731
if ( verbosity > 0 ) fprintf (stderr ,"Computed %d-smooth factorizations of m <= %d using %.3fMB of memory (%.3fs)\n" , MAXP ,MAXM ,4.0 * (MAXM + (Fend - F ))/(1 <<20 ),get_time ()- start );
722
732
733
+ char rbuf [32 ];
734
+ if ( a == 1 ) sprintf (rbuf ,"N/%d" ,b ); else sprintf (rbuf ,"%dN/%d" ,a ,b );
735
+
723
736
start = get_time ();
724
737
if ( maxN > minN ) {
725
738
if ( create || !hintfile ) {
@@ -729,15 +742,17 @@ int main (int argc, char *argv[])
729
742
if ( hintfile && !fp ) { fprintf (stderr , "Error creating hint-file %s\n" , hintfile ); return -1 ; }
730
743
int64_t N = minN ;
731
744
while ( N <= maxN ) {
732
- t = tbound (N ,fast ,exhaustive ,verbosity ,verify );
733
- if ( 3 * t < N ) break ;
734
- if ( verbosity >= 0 ) fprintf (stderr ,"t(%ld) >= %ld (t-N/3 >= %ld) (%.3fs)\n" , N , t , t - cdiv (N , 3 ), get_time ()- start );
745
+ t = tbound (N ,a , b , fast ,exhaustive ,verbosity ,verify );
746
+ if ( b * t < a * N ) break ;
747
+ if ( verbosity >= 0 ) fprintf (stderr ,"t(%ld) >= %ld (t-%s >= %ld) (%.3fs)\n" , N , t , rbuf , t - cdiv (a * N , b ), get_time ()- start );
735
748
if ( fp ) fprintf (fp ,"%ld:%ld\n" ,N ,t );
736
- N = 3 * t + 1 ;
749
+ N = b * t /a + 1 ;
750
+ }
751
+ if ( N > maxN ) {
752
+ fprintf (stderr ,"Verified the %s Erdős-Guy-Selfridge conjecture for all N in [%ld,%ld] (%.3fs)\n" ,rbuf ,minN ,maxN ,get_time ()- start );
737
753
}
738
- if ( N > maxN ) fprintf (stderr ,"Verified the Erdős-Guy-Selfridge conjecture for N in [%ld,%ld] (%.3fs)\n" ,minN ,maxN ,get_time ()- start );
739
- else if ( N == minN ) fprintf (stderr ,"Unable to verify Erdős-Guy-Selfridge conjecture for N=%ld (%.3fs)\n" ,minN ,get_time ()- start );
740
- else fprintf (stderr ,"Only able to verify the Erdős-Guy-Selfridge conjecture for N in [%ld,%ld] (%.3fs)\n" ,minN ,N - 1 ,get_time ()- start );
754
+ else if ( N == minN ) fprintf (stderr ,"Unable to verify the %s Erdős-Guy-Selfridge conjecture for N=%ld in (%.3fs)\n" ,rbuf ,minN ,get_time ()- start );
755
+ else fprintf (stderr ,"Only able to verify the %s Erdős-Guy-Selfridge conjecture for N in [%ld,%ld] (%.3fs)\n" ,rbuf ,minN ,N - 1 ,get_time ()- start );
741
756
} else {
742
757
FILE * fp = fopen (hintfile ,"r" ); if (!fp ) { fprintf (stderr , "Error opening hint-file %s\n" , hintfile ); return -1 ; }
743
758
char buf [256 ];
@@ -746,30 +761,30 @@ int main (int argc, char *argv[])
746
761
int64_t N = atol (buf );
747
762
char * s = strchr (buf ,':' ); if (!s ) { fprintf (stderr , "Error parsing line %s\n" , buf ); return -1 ; }
748
763
t = atol (s + 1 );
749
- if ( 3 * t < N ) { fprintf (stderr , "Invalid N:t in hint file: 3 *%ld < %ld\n" , t , N ); return -1 ; }
764
+ if ( b * t < a * N ) { fprintf (stderr , "Invalid N:t in hint file: %d *%ld < %d*% ld\n" , b , t , a , N ); return -1 ; }
750
765
double timer = get_time ();
751
766
if ( tfac (N ,t ,fast ,0 ,verbosity ,verify ,0 ) < N ) { fprintf (stderr , "Failed to verify t(%ld) >= %ld !\n" , N ,t ); return -1 ; }
752
767
if (!minV ) {
753
768
if ( N > minN ) { fprintf (stderr , "Hint file starting N=%ld above range minimum %ld\n" , N , minN ); return -1 ; }
754
769
minV = N ;
755
- maxV = 3 * t ;
770
+ maxV = b * t / a ;
756
771
} else {
757
772
if ( N > maxV + 1 ) { fprintf (stderr , "Hint file starting N=%ld leaves a gap!\n" , N ); return -1 ; }
758
- if ( 3 * t <= maxV ) { fprintf (stderr , "Hint at N=%ld did not extend verified range!\n" , N ); return -1 ; }
759
- maxV = 3 * t ;
773
+ if ( b * t <= a * maxV ) { fprintf (stderr , "Hint at N=%ld did not extend verified range!\n" , N ); return -1 ; }
774
+ maxV = b * t / a ;
760
775
}
761
776
if ( verbosity >= 0 ) printf ("t(%ld) >= %ld (%.3fs)\n" , N , t , get_time ()- timer );
762
777
if ( maxV >= maxN ) break ;
763
778
}
764
779
if ( minV > minN || maxV < maxN ) { fprintf (stderr , "Hint file only allowed verification [%ld,%ld]\n" , minV ,maxV ); return -1 ; }
765
- fprintf (stderr ,"Verified the Erdős-Guy-Selfridg conjecture for N in [%ld,%ld] (%.3fs)\n" ,minN ,maxN ,get_time ()- start );
780
+ fprintf (stderr ,"Verified the %s Erdős-Guy-Selfridg conjecture for N in [%ld,%ld] (%.3fs)\n" , rbuf ,minN ,maxN ,get_time ()- start );
766
781
}
767
782
} else {
768
783
int64_t N = minN ;
769
784
if ( t && exhaustive ) { t = 0 ; fprintf (stderr ,"Ignoring specified value of t and searching for optimal value\n" ); }
770
785
if ( !t ) {
771
- t = tbound (N ,fast ,exhaustive ,verbosity ,verify );
772
- if ( t ) printf ("t(%ld) >= %ld (%s %s) with (t-ceil(N/3)) = %ld (%.3fs)\n" , N , t , exhaustive ? "exhaustive" : "heuristic" , fast ? "fast" : "greedy" ,( t - cdiv (N , 3 ) ),get_time ()- start );
786
+ t = tbound (N ,a , b , fast ,exhaustive ,verbosity ,verify );
787
+ if ( t ) printf ("t(%ld) >= %ld (%s %s) with t-%s = %ld (%.3fs)\n" , N , t , exhaustive ? "exhaustive" : "heuristic" , fast ? "fast" : "greedy" ,rbuf , t - cdiv (a * N , b ),get_time ()- start );
773
788
else fprintf (stderr ,"failed to prove t(%ld) >= %ld (%.3fs)\n" , N , cdiv (N ,3 ), get_time ()- start );
774
789
} else {
775
790
int64_t cnt = tfac (N ,t ,fast ,0 ,verbosity ,verify ,dumpfile );
0 commit comments