- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm working on a ProjectEuler problem, number 36 to be exact.
I'm having an issue when converting an integer to a string in order to send them to my palindrome(string) function which returns a logical
I have played around with different syntaxes for the character array definition for the string, but the current code below is the only way I could get it to compile.
---START CODE---
program Euler36
implicit none
integer :: time_start, time_finish, clock_finish, solution = 0, i
character, allocatable :: s1(:)
call SYSTEM_CLOCK(time_start)
do i = 1,1000000
write (s1,'(I0)') i
print*,s1
if (palindrome(s1)) then
write(s1,'(B0)') i
print*,s1
if (palindrome(s1)) then
solution = solution + 1
end if
end if
end do
call SYSTEM_CLOCK(time_finish)
clock_finish = time_finish - time_start
write (*,"(A10,I10,//,A21,I5,A14)") "Solution: ",solution,"Program completed in ",clock_finish," milliseconds."
contains
logical function palindrome(str)
character, allocatable :: str(:)
integer :: i
do i = 0,len(str)/2
if (str(i+1) /= str((len(str))-i)) then
palindrome = .false.
return
end if
end do
palindrome = .true.
return
end
end program Euler36
---END CODE---
The output to command line states "Fortran runtime error: End of record" and then prints backtrace hexadecimal addresses.
The error occurs on line "write (s1,'(I0)') i" which from multiple tutorials I've seen is the "correct" way to do this.
How can I properly assign the integers to string variables such that they can be sent correctly to my palindrome(string) function?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You cannot allocate a string with a write. You could:
character(:), allocatable :: s1
character(10) :: s10 ! 10 chars is big enough
write (s10,'(I0)') i
s1 = trim(s10) ! allocates s1 to exact length
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You cannot allocate a string with a write. You could:
character(:), allocatable :: s1
character(10) :: s10 ! 10 chars is big enough
write (s10,'(I0)') i
s1 = trim(s10) ! allocates s1 to exact length
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A brief look at the Pure Math behind the problem suggests that the decimal and the binary palindromes each have a numerical pattern, the decimal based on the series, 1, 10, 11, 110, etc.. The binary based on 2 and 5.
You should be able to construct a simple set of 3 do loops that will cover the range 0 to 999,999 as 1,000,000 can never be a palindrome.
You break the numbers into even and odd lengths and then do your comparison, starting from the outside, as once you find a potential decimal one then the next length has none, the length varies based on the number of digits. But 11 is a potential and then the next one is 22, 33 etc.. there is no need to search in between. There is no reason to omit zero as it has no leading zeros, it is a good number.
A similar exercise in the binary should yield the final set.
So , 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9 are palindromes, but 10 is not, 11 is - but in binary the 0, 1, 11, 101, 111, 1001, 1111 etc. match 0, 1, 3, 5, etc..
At the next stage, 11, 22, 33, 44, 55, 66 ,77, etc. then 101, 111, 121, 131, 141, 151,161,171,181, 191 - they always come in groups of 9 below 1000. I think there are 9 * 11 = 99, below 1,000.
My old Pure math professor once said, it is correct but it is not elegant.
My guess is about 100000 potential palindromes in the first pass and it comes down from there, you would need three passes as there are 3 sets of doubles in 999999.
Just a thought. But you can assemble them in a 6 unit block and then drop all the zeros.
000000
000100
000200
000300
000400
000500
000600
000700
000800
000900
001100
002200
003300
...
009900
001010
001110
001210
...
As well any ending in 2, 4, 6, or 8 is likely to generate a 10 ending or similar.
So there are about I think 40 to 50 below 1000 that need to be checked for binary palindromes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I used EXCEL to test until EXCEL crashed at 512 in the conversion.
0 0 0 0
0 0 1 1
0 0 3 11
0 0 5 101
0 0 7 111
0 0 9 1001
0 3 3 100001
0 9 9 1100011
3 1 3 100111001
It was fun, in LISP using CAR and CDR it would be a simple exercise.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The site crashed as I tried to log on to this post set.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
of the 200 or so leaders listed on the Euler Problem solving web site, only 1 uses Fortran.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
else if(n .eq. 21 .and. bin(1:1) .eq. bin(21:21) .and. bin(2:2) .eq. bin(20:20) .and. bin(3:3) .eq. bin(19:19) &
.and. bin(4:4) .eq. bin(18:18) .and. bin(5:5) .eq. bin(17:17) .and. bin(6:6) .eq. bin(16:16) .and. bin(7:7) .eq. bin(15:15) .and. bin(8:8) .eq. bin(14:14) &
.and. bin(9:9) .eq. bin(13:13) .and. bin(10:10) .eq. bin(12:12) ) then
It was interesting to solve this problem. The Euler people ask that you do not post the solution, it was 167 lines of code, sans comments.
The bin is a character64 that holds the binary number being tested. n is the trimmed length, is there a way to make this simpler, it is quite brutish.
write(bin_representation, fmt='(B0)') i
I was thinking a do loop ?
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page