problem_18 Program

Uses

  • program~~problem_18~~UsesGraph program~problem_18 problem_18 iso_fortran_env iso_fortran_env program~problem_18->iso_fortran_env module~aoc_utilities aoc_utilities program~problem_18->module~aoc_utilities module~aoc_utilities->iso_fortran_env

Calls

program~~problem_18~~CallsGraph program~problem_18 problem_18 proc~clock_end aoc_utilities::clock%clock_end program~problem_18->proc~clock_end proc~clock_start aoc_utilities::clock%clock_start program~problem_18->proc~clock_start proc~go~2 problem_18::go program~problem_18->proc~go~2 interface~split aoc_utilities::split proc~go~2->interface~split proc~destination problem_18::destination proc~go~2->proc~destination proc~hex2int aoc_utilities::hex2int proc~go~2->proc~hex2int proc~number_of_lines_in_file aoc_utilities::number_of_lines_in_file proc~go~2->proc~number_of_lines_in_file proc~parea aoc_utilities::parea proc~go~2->proc~parea proc~read_line aoc_utilities::read_line proc~go~2->proc~read_line proc~split1 aoc_utilities::split1 interface~split->proc~split1 proc~split2 aoc_utilities::split2 interface~split->proc~split2 proc~expand_vector aoc_utilities::expand_vector proc~split1->proc~expand_vector proc~split2->proc~split1

Variables

Type Attributes Name Initial
integer(kind=ip) :: iresult

Functions

pure function destination(initial, direction, steps) result(final)

get destination point

Arguments

Type IntentOptional Attributes Name
integer(kind=ip), intent(in), dimension(2) :: initial
character(len=1), intent(in) :: direction
integer(kind=ip), intent(in) :: steps

Return Value integer(kind=ip), dimension(2)

x,y of desination point


Subroutines

subroutine go(partb, iresult)

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: partb

if solving part b

integer(kind=ip), intent(out) :: iresult

Source Code

program problem_18

    use aoc_utilities
    use iso_fortran_env

    implicit none

    integer(ip) :: iresult

    call clk%tic()

    call go(.false., iresult); write(*,*) '18a:', iresult
    call go(.true., iresult);  write(*,*) '18b:', iresult

    call clk%toc('18')

    contains

    subroutine go(partb, iresult)

        logical,intent(in) :: partb !! if solving part b
        integer(ip),intent(out) :: iresult

        integer :: iunit, iline, n_lines, n
        character(len=:),allocatable :: line, hex
        type(string),dimension(:),allocatable :: vals
        character(len=1) :: direction
        integer(ip),dimension(2) :: iloc, iloc2
        integer(ip) :: ival, isteps
        real(wp),dimension(:),allocatable :: xvec,yvec

        character(len=1),dimension(0:3) :: direction_str = ['R', 'D', 'L', 'U'] ! directions for part b : 0,1,2,3

        ! open(newunit=iunit, file='inputs/day18_test.txt', status='OLD')
        open(newunit=iunit, file='inputs/day18.txt', status='OLD')
        n_lines = number_of_lines_in_file(iunit)

        iloc = [0,0] ! where to start
        isteps = 0
        xvec = [0]; yvec = [0]
        do iline = 1, n_lines
            line = read_line(iunit)
            vals = split(line, ' ') ! direction, number, (hex)
            if (partb) then
                ! values encoded in hex
                hex       = vals(3)%str
                ival      = hex2int(hex(3:7))
                direction = direction_str(int(hex(8:8)))
            else
                direction = vals(1)%str
                ival = int(vals(2)%str)
            end if
            isteps = isteps + ival ! keep track of the total perimeter size
            iloc2 = destination(iloc, direction, ival) ! destination oint
            xvec = [xvec, real(iloc2(1),wp)] ! save the points of the polygon
            yvec = [yvec, real(iloc2(2),wp)] !
            iloc = iloc2 ! update for next move
        end do
        close(iunit)

        ! the area including the boundary = area + 1/2 the perimeter + 1
        ! using NSWC parea function!
        n = size(xvec)
        iresult = int(abs(parea(yvec, xvec, n)) + real(isteps,wp)/2_ip + 1_ip, ip)

    end subroutine go

    pure function destination(initial, direction, steps) result(final)
        !! get destination point
        integer(ip),dimension(2),intent(in) :: initial
        character(len=1),intent(in) :: direction
        integer(ip),intent(in) :: steps
        integer(ip),dimension(2) :: final !! x,y of desination point
        select case (direction)
        case('R'); final = [initial(1), initial(2)+steps]
        case('L'); final = [initial(1), initial(2)-steps]
        case('D'); final = [initial(1)+steps, initial(2)]
        case('U'); final = [initial(1)-steps, initial(2)]
        end select
    end function destination

end program problem_18