- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I stumbled across this little gem, it is correct - checked it with excel -- did they likely do it in Fortran and what algorithm do you think they used?
This paper sets out some of the findings as well from 1967, this is a big search and overflow would be a real issue
The two are from the aerospace co - why would they be interested in this pure math --
Link Copied
- « Previous
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
subroutine FindCounterExamples(uLimit)
integer(INT64), intent(in) :: uLimit
logical :: found
integer(INT64) :: maxRoot, m
integer(INT64) :: iterations
integer(INT64) :: a, b, c, d, n
integer(INT64) :: sum
real(REAL64) :: seconds
integer(INT64), rank(1), allocatable :: powers
integer(INT64), rank(1), allocatable :: roots
type(TTimer) :: timer
call timer % Start()
call DisplayHeader(uLimit)
maxRoot = LargestRoot(uLimit)
m = HashTableSize(uLimit)
call BuildFifthPowers(maxRoot, powers)
call BuildFifthRoots(maxRoot, m, powers, roots)
iterations = 0
do a = 1, uLimit
do b = a, uLimit
do c = b, uLimit
do d = c, uLimit
iterations = iterations + 1
sum = powers(a) + powers(b) + powers(c) + powers(d)
call TestFifthPower(sum, powers, roots, n, found)
if (found) then
call DisplayResult(a, b, c, d, n)
end if
end do
end do
end do
end do
call timer % Stop()
seconds = timer % Elapsed()
call DisplaySummary(iterations, seconds)
end subroutine FindCounterExamplesThis is the main loop. Hopefully the gist is fairly clear. I'll endeavour to attach the Visual Studio solution so you can see all the details, and maybe leave in my comments at the top of the file EulersConjecture.f90 that records a summary of the changes I made.
I call a couple of subroutines before the loops to set up some data that is used in the main loop. The 5th powers are all pre-computed and stored in powers, e.g powers(i) = i**5. Similarly, roots is a hash table that is the inverse of powers, e.g. given an integer 5th power i**5, use roots to recover the value i. This is used in the subroutine TestFifthPowers to determine if the sum of 5th powers is itself a 5th power. The function HashTableSize is used to determine a smallish hash table size that also ensures there are no hash collisions.
Finally, the subroutine TestFifthPowers also makes use of the number theorist's trade secret posted above by (at that time) Mr Mecej4, to avoid testing numbers that cannot be 5th powers.
I tried a couple of additional things that are not present in the attached code.
- A running total of the 5th power partial sums in the outer loops. This saved an additional 0.2s
- Inlining the functionality from the subroutine TestFifthPower. This saved an additional 0.4s.
But it made the source code too ugly, so I reverted those changes.
Here are the details for TestFifthPowers...
subroutine TestFifthPower(n, powers, roots, i, found)
! Test if n is a 5th power.
! If it is, return the value i such that i**5 = n.
integer(INT64), intent(in) :: n
integer(INT64), rank(1), intent(in) :: powers
integer(INT64), rank(1), intent(in) :: roots(0:)
integer(INT64), intent(out) :: i
logical, intent(out) :: found
integer(INT64) :: m
integer(INT32) :: k
! Early exit. If n does not meet the requirements for a 5th power, no need to test further.
if (.not. IsPotentialFifthPower(n)) then
found = .false.
return
end if
! Use the roots lookup table to get a candidate root, then test it.
m = Size(roots)
k = Modulo(n, m)
i = roots(k)
found = (powers(i) == n)
end subroutine TestFifthPower
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I downloaded your Zip file, extracted the files, then built and ran your program. Nice work, @David-F8 ! A nice feature to add would be to take each output solution, find the GCF (greatest common factor) of the five numbers that are raised to the fifth power, and divide each of them by the GCF, and then output the "primitive solution", as it is called.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Agreed. But I'm definitely not going to do that.
After a bit of tweaking, I have my run time down to 4.4s.
But, apart from multi-threading, I think I'm done with that particular approach.
Working on another idea now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Forgot...
I've been running it from the command line. The first (only) command line argument is the upper limit for the search. I've been using 600.
PS C:\Users\David\Source\Fortran\EulersConjecture\EulersConjecture> .\x64\Release\EulersConjecture.exe 600
Testing numbers 1...600
Determine table size (0.000 seconds)
Building 5th powers (0.000 seconds)
Building 5th roots (0.000 seconds)
27^5 + 84^5 + 110^5 + 133^5 = 144^5
54^5 + 168^5 + 220^5 + 266^5 = 288^5
81^5 + 252^5 + 330^5 + 399^5 = 432^5
108^5 + 336^5 + 440^5 + 532^5 = 576^5
5454165150 iterations in 5.636 seconds (9.677+08 iter/s)
Done.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wouldn't be quicker to reverse the problem? For each 5th power, try to find a combination of 5th power numbers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know what you mean by "reverse the problem". If you know n^5, and you wish to find i,j,k,l,m such that i^5+j^5+k^5+l^5+m^5=n^5, there are two obstacles. 1. How do you know that a solution exists? 2. If no solution exists, is your algorithm capable of detecting that fact, and can it end the calculation safely?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I thought that reversing the problem might be a knapsack-type approach: Take one of the fifth powers as a starting point (the target sum), and try to find 4 smaller fifth powers that add to the target sum.
This is a hard problem in general, not sure if it would be beneficial for this particular problem. In the worst case (which is most of time) you'd end up doing an (n choose 4) search through the list of fifth powers and not find a solution... and you need to do this n times, one for each of the target sums.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My idea was for each n^5 test the sum of 5 i^5in 5 nested loops. Each inner loop will be limited to the value of the outer loop and can be stopped as soon as the sum overflow n^5. Barely it seems possible that would limit the number of iterations.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you look at @David-F8's post in this thread, you will see nested loops of the type that you suggest. The key is to make sure that the loops cover just the needed combinations, and no more.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something like that
do n=1,nmax
do i=1,n-1
do j=1,i-1
sum(1)=pow5(i)+pow5(j)
if (sum(1).ge.pow5(n)) exit
do k=1,j-1
sum(2)=sum(1)+pow5(k)
if (sum(2).ge.pow5(n)) exit
do l=1,k-1
sum(3)=sum(2)+pow5(l)
if (sum(3).ge.pow5(n)) exit
do m=1,l-1
sum(4)=sum(3)+pow5(m)
if (sum(4).eq.pow5(n)) then
write 'OK'
exit
endif
if (sum(4).gt.pow5(n)) exit
enddo
enddo
enddo
enddo
enddo
enddo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, the new approach I alluded to above dropped out quite quickly.
Still single threaded, no longer using any number theory tricks, but down to 1.4s now.
Testing numbers 1...600
Building 5th powers (0.000 seconds)
Building power tables (0.000 seconds)
Building power map (0.016 seconds)
( 27, 84, 110, 133)
( 54, 168, 220, 266)
( 81, 252, 330, 399)
(108, 336, 440, 532)
791 iterations in 1.464 seconds.And all the solutions for values up to 999 in under 10s.
( 27, 84, 110, 133)
( 54, 168, 220, 266)
( 81, 252, 330, 399)
(108, 336, 440, 532)
(135, 420, 550, 665)
(162, 504, 660, 798)
(189, 588, 770, 931)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Final update:
- 1.1s for all values up to 600.
- 8.7s for all values up to 999.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
- Next »