Advertisement
Der_Teufel

Day 16 AoC 2023

Dec 16th, 2023
1,905
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. program day16
  2.     implicit none
  3.     integer, parameter :: dim = 110
  4.     character, dimension(dim,dim) :: contraption
  5.     integer, dimension(dim,dim) :: visited
  6.     integer :: i, j, ecode, solution, x, y
  7.     integer, parameter :: in = 50
  8.  
  9.     open(in, file="day16.txt", action="read", iostat=ecode)
  10.     if ( ecode .eq. 0 ) then
  11.         do j = 1, dim
  12.             read (in, '(110(a))', iostat=ecode) contraption(:,j)
  13.             if ( ecode .ne. 0 ) exit
  14.         end do
  15.         close(in)
  16.  
  17.         call visit(visited, 0, 1, 0)
  18.         solution = viscount(visited)
  19.         write (*, '("Part 1: ", i0)') solution
  20.  
  21.         solution = 0
  22.         do i = 1, dim
  23.             call visit(visited, 0, i, 0)
  24.             solution = max(solution, viscount(visited))
  25.             call visit(visited, dim + 1, i, 3)
  26.             solution = max(solution, viscount(visited))
  27.         end do
  28.         do i = 1, dim
  29.             call visit(visited, i, dim + 1, 1)
  30.             solution = max(solution, viscount(visited))
  31.             call visit(visited, i, 0, 3)
  32.             solution = max(solution, viscount(visited))
  33.         end do
  34.         write (*, '("Part 2: ", i0)') solution
  35.  
  36.     else
  37.         print '(a)', "Error opening file"
  38.     end if
  39.  
  40. contains
  41.  
  42.     integer function viscount(visited)
  43.         integer, dimension(dim,dim), intent(in) :: visited
  44.         integer :: x, y
  45.         viscount = 0
  46.         do x = 1, dim
  47.             do y = 1, dim
  48.                 if ( visited(x,y) .gt. 0 ) viscount = viscount + 1
  49.             end do
  50.         end do
  51.     end function viscount
  52.  
  53.     subroutine visit(visited, startx, starty, startd)
  54.         integer, dimension(dim,dim), intent(inout) :: visited
  55.         integer, intent(in) :: startx, starty, startd
  56.         integer, dimension(0:100) :: visitorsx, visitorsy, direction
  57.         integer :: next_visitor, currx, curry, currd
  58.         visited = 0; next_visitor = 0
  59.         visitorsx(next_visitor) = startx
  60.         visitorsy(next_visitor) = starty
  61.         direction(next_visitor) = startd
  62.         next_visitor = next_visitor + 1
  63.  
  64.         do while ( next_visitor .gt. 0 )
  65.             next_visitor = next_visitor - 1
  66.             currx = visitorsx(next_visitor)
  67.             curry = visitorsy(next_visitor)
  68.             currd = direction(next_visitor)
  69.  
  70.             if ( 0 .eq. currd ) then ! RIGHT
  71.                 currx = currx + 1
  72.             else if ( 1 .eq. currd ) then ! UP
  73.                 curry = curry - 1
  74.             else if ( 2 .eq. currd ) then ! LEFT
  75.                 currx = currx - 1
  76.             else if ( 3 .eq. currd ) then ! DOWN
  77.                 curry = curry + 1
  78.             else ! INVALID DIRECTION
  79.                 exit
  80.             end if
  81.  
  82.             if ( currx .eq. 0 .or. curry .eq. 0 .or. currx .eq. (dim + 1) .or. curry .eq. (dim + 1)) cycle
  83.  
  84.             if ( iand(visited(currx,curry), ishft(1, currd)) .gt. 0 ) cycle
  85.             visited(currx, curry) = ior(visited(currx, curry), ishft(1, currd))
  86.  
  87.             if ( contraption(currx, curry) .eq. '.' ) then
  88.                 visitorsx(next_visitor) = currx
  89.                 visitorsy(next_visitor) = curry
  90.                 next_visitor = next_visitor + 1
  91.             else if ( contraption(currx, curry) .eq. '|' ) then
  92.                 if ( currd .eq. 1 .or. currd .eq. 3 ) then ! UP or DOWN
  93.                     visitorsx(next_visitor) = currx
  94.                     visitorsy(next_visitor) = curry
  95.                     next_visitor = next_visitor + 1
  96.                 else
  97.                     ! push UP
  98.                     visitorsx(next_visitor) = currx
  99.                     visitorsy(next_visitor) = curry
  100.                     direction(next_visitor) = 1
  101.                     next_visitor = next_visitor + 1
  102.                     ! push DOWN
  103.                     visitorsx(next_visitor) = currx
  104.                     visitorsy(next_visitor) = curry
  105.                     direction(next_visitor) = 3
  106.                     next_visitor = next_visitor + 1
  107.                 end if
  108.             else if ( contraption(currx, curry) .eq. '-' ) then
  109.                 if ( currd .eq. 0 .or. currd .eq. 2 ) then ! LEFT or RIGHT
  110.                     visitorsx(next_visitor) = currx
  111.                     visitorsy(next_visitor) = curry
  112.                     next_visitor = next_visitor + 1
  113.                 else
  114.                     ! push RIGHT
  115.                     visitorsx(next_visitor) = currx
  116.                     visitorsy(next_visitor) = curry
  117.                     direction(next_visitor) = 0
  118.                     next_visitor = next_visitor + 1
  119.                     ! push LEFT
  120.                     visitorsx(next_visitor) = currx
  121.                     visitorsy(next_visitor) = curry
  122.                     direction(next_visitor) = 2
  123.                     next_visitor = next_visitor + 1
  124.                 end if
  125.             else if ( contraption(currx, curry) .eq. '/' ) then
  126.                 if ( 0 .eq. currd ) then ! RIGHT
  127.                     visitorsx(next_visitor) = currx
  128.                     visitorsy(next_visitor) = curry
  129.                     direction(next_visitor) = 1
  130.                     next_visitor = next_visitor + 1
  131.                 else if ( 1 .eq. currd ) then ! UP
  132.                     visitorsx(next_visitor) = currx
  133.                     visitorsy(next_visitor) = curry
  134.                     direction(next_visitor) = 0
  135.                     next_visitor = next_visitor + 1
  136.                 else if ( 2 .eq. currd ) then ! LEFT
  137.                     visitorsx(next_visitor) = currx
  138.                     visitorsy(next_visitor) = curry
  139.                     direction(next_visitor) = 3
  140.                     next_visitor = next_visitor + 1
  141.                 else if ( 3 .eq. currd ) then ! DOWN
  142.                     visitorsx(next_visitor) = currx
  143.                     visitorsy(next_visitor) = curry
  144.                     direction(next_visitor) = 2
  145.                     next_visitor = next_visitor + 1
  146.                 end if
  147.             else if ( contraption(currx, curry) .eq. '\' ) then
  148.                if ( 0 .eq. currd ) then ! RIGHT
  149.                    visitorsx(next_visitor) = currx
  150.                    visitorsy(next_visitor) = curry
  151.                    direction(next_visitor) = 3
  152.                    next_visitor = next_visitor + 1
  153.                else if ( 1 .eq. currd ) then ! UP
  154.                    visitorsx(next_visitor) = currx
  155.                    visitorsy(next_visitor) = curry
  156.                    direction(next_visitor) = 2
  157.                    next_visitor = next_visitor + 1
  158.                else if ( 2 .eq. currd ) then ! LEFT
  159.                    visitorsx(next_visitor) = currx
  160.                    visitorsy(next_visitor) = curry
  161.                    direction(next_visitor) = 1
  162.                    next_visitor = next_visitor + 1
  163.                else if ( 3 .eq. currd ) then ! DOWN
  164.                    visitorsx(next_visitor) = currx
  165.                    visitorsy(next_visitor) = curry
  166.                    direction(next_visitor) = 0
  167.                    next_visitor = next_visitor + 1
  168.                end if
  169.            end if
  170.        end do
  171.    end subroutine visit
  172. end program day16
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement