Reputation: 21
I am working on a Fortran95 solution to Project Euler problem 22. I have it working correctly in the three complilers listed in the title, but for some reason the array labelled names
is filled incorrectly when compiled with ifx
/ifort
. It's just a jumbled mess with a bunch of 1-character names and others that make no sense
Below is my solution. Note that open_data_file
is from utils, and I will include it below. Some of my debug prints are not indented, as they are entirely temporary
! Project Euler Problem 22
!
! Problem:
!
! Using names.txt (right click and 'Save Link/Target As...'), a 46K text file
! containing over five-thousand first names, begin by sorting it into
! alphabetical order. Then working out the alphabetical value for each name,
! multiply this value by its alphabetical position in the list to obtain a name
! score.
!
! For example, when the list is sorted into alphabetical order, COLIN, which is
! worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would
! obtain a score of 938 × 53 = 49714.
!
! What is the total of all the name scores in the file?
module Problem0022
use constants
use utils
implicit none
integer, parameter :: name_count = 5163
contains
integer(i18t) function p0022() result(answer)
character(len=DATA_MAX_NAME_SIZE), parameter :: file_name = "p0022_names.txt"
character(len=DATA_MAX_NAME_SIZE), dimension(name_count) :: names
character(len=DATA_MAX_NAME_SIZE) :: temp
character(len=1) :: current_char
integer(i18t) :: score
integer :: ios, unit, i, j, k
i = 1
j = 1
k = 1
answer = 0
names = ''
unit = open_data_file(file_name, .true., 1)
do
read(unit, rec=j, IOSTAT=ios) current_char
j = j + 1
if (ios /= 0) then
exit
end if
select case (current_char)
case (',')
i = i + 1
k = 1
case ('"')
case default
names(i)(k:k) = current_char
k = k + 1
end select
end do
do i=1, size(names)
print *, names(i)
end do
close(unit)
do i = 1, size(names)
do j = 1, size(names) - i
if (names(j) > names(j + 1)) then
temp = names(j)
names(j) = names(j + 1)
names(j + 1) = temp
end if
end do
end do
do i=1, size(names)
print *, names(i)
end do
close(unit)
do i = 1, name_count
score = 0
do j = 1, len_trim(names(i))
score = score + ichar(names(i)(j:j)) - ichar('A') + 1
end do
answer = answer + score * i
end do
end function p0022
end module Problem0022
integer function open_data_file(name, direct, recl) result(unit)
character(len=DATA_MAX_NAME_SIZE), intent(in) :: name
logical, intent(in), optional :: direct
integer, intent(in), optional :: recl
integer :: ios
unit = prev_unit + 1
prev_unit = unit
if (present(direct) .and. present(recl) .and. direct) then
open(unit=unit, file=("../_data/" // name), status='old', action='read', iostat=ios, access='direct', recl=recl)
else
open(unit=unit, file=("../_data/" // name), status='old', action='read', iostat=ios)
end if
if (ios /= 0) then
print *, "Error opening file: ../_data/" // name
return
end if
end function
I tried reading in sequential mode, checking the file encoding, adjusting the type of current_character, and some degree of debug printing. Due to environment problems, I have some difficulty using gdb with Fortran specifically. I expect behavior to match that of other compilers.
Upvotes: 1
Views: 67