ipound Function

recursive function ipound(ipattern, ints)

Arguments

Type IntentOptional Attributes Name
integer(kind=ip), intent(in), dimension(:) :: ipattern

first char is a #

integer(kind=ip), intent(in), dimension(:) :: ints

Return Value integer(kind=ip)


Calls

proc~~ipound~~CallsGraph proc~ipound problem_12b::ipound ints_tmp ints_tmp proc~ipound->ints_tmp ipattern_tmp ipattern_tmp proc~ipound->ipattern_tmp proc~go~4 problem_12b::go proc~ipound->proc~go~4 proc~go~4->proc~ipound proc~get_from_cache~2 aoc_cache_module::function_cache%get_from_cache proc~go~4->proc~get_from_cache~2 proc~ipoint problem_12b::ipoint proc~go~4->proc~ipoint proc~put_in_cache~2 aoc_cache_module::function_cache%put_in_cache proc~go~4->proc~put_in_cache~2 proc~vector_djb_hash~2 aoc_cache_module::vector_djb_hash proc~get_from_cache~2->proc~vector_djb_hash~2 proc~ipoint->proc~go~4

Called by

proc~~ipound~~CalledByGraph proc~ipound problem_12b::ipound proc~go~4 problem_12b::go proc~ipound->proc~go~4 proc~go~4->proc~ipound proc~ipoint problem_12b::ipoint proc~go~4->proc~ipoint proc~ipoint->proc~go~4 program~problem_12b problem_12b program~problem_12b->proc~go~4

Source Code

    recursive integer(ip) function ipound(ipattern, ints)
        integer(ip),dimension(:),intent(in) :: ipattern !! first char is a #
        integer(ip),dimension(:),intent(in) :: ints

        integer(ip),dimension(:),allocatable :: this_group

        ! check for the number of # that correspond to the first group
        if (size(ipattern)>=ints(1)) then
            this_group = ipattern(1:ints(1))
            where (this_group==QUESTION) this_group = NUMBER ! replace ? with #
            if (any(this_group/=NUMBER)) then
                ! can't fit all the #'s so not valid
                ipound = 0
                return
            else
                ! so far so good
            end if
        else
            ! not enough room to hold all the #'s
            ipound = 0
            return
        end if

        if (size(ipattern) == ints(1)) then
            ! if this is the last group, then we are done
            ipound = merge(1, 0, size(ints)==1)
        else
            ! the next character after this number must be a ? or .
            if (size(ipattern)>=ints(1)+1) then
                if (any(ipattern(ints(1)+1)==[QUESTION,POINT])) then
                    block
                        integer(ip),dimension(:),allocatable :: ipattern_tmp, ints_tmp ! to handle edge cases
                        ! skip it and process the next group
                        if (size(ipattern)>=ints(1)+2) then
                            ipattern_tmp = ipattern(ints(1)+2:)
                        else
                            allocate(ipattern_tmp(0))
                        end if
                        if (size(ints)>=2) then
                            ints_tmp = ints(2:)
                        else
                            allocate(ints_tmp(0))
                        end if
                        ipound = go(ipattern_tmp, ints_tmp)
                        return
                    end block
                end if
            end if

            ! not valid at this point
            ipound = 0
        end if

        end function ipound