re: AoC Day 3: No Matter How You Slice It VIEW POST

FULL DISCUSSION
 

This seemed like a natural job for Fortran!

Part 1

No, really, it has nice array operation and slicing syntax! I've just stretched out a big array, added 1 everywhere there's a claim, and then counted the number of elements where there's an element greater than 1.

program aoc31
      use ISO_FORTRAN_ENV
      implicit none
      integer, dimension(0:1023,0:1023) :: cloth
      logical, dimension(0:1023,0:1023) :: cloth_mask
      integer :: id, cut_x, cut_y, cut_width, cut_height
      integer :: overlaps
      integer :: io_status

      cloth = 0

      io_status = 0

      do
        read (*,*,iostat=io_status) id, cut_x, cut_y, cut_width, cut_height
        if (io_status /= 0) then
          exit
        end if
        cloth(cut_x:cut_x+cut_width-1, cut_y:cut_y+cut_height-1) = &
         cloth(cut_x:cut_x+cut_width-1, cut_y:cut_y+cut_height-1) + 1
      end do

      cloth_mask = (cloth > 1)
      overlaps = count(cloth_mask)

      write(*,*) "Overlaps: ", overlaps
end program aoc31
Part 2

Part 2 was trickier, and I had to use a similar solution to @rpalo , going over each claim again; but then I checked whether the sum of the cut elements was the same as its area to determine whether it was a unique claim. I could have done a similar count-based method to part 1, but I thought of this way first.

program aoc32
      use ISO_FORTRAN_ENV
      implicit none
      integer, dimension(0:1023,0:1023) :: cloth
      logical, dimension(0:1023,0:1023) :: cloth_mask
      integer :: id, cut_x, cut_y, cut_width, cut_height
      integer :: overlaps
      integer :: io_status

      cloth = 0

      io_status = 0

      open (unit=5, file="input.simplified")
      do
        read (5,*,iostat=io_status) id, cut_x, cut_y, cut_width, cut_height
        if (io_status /= 0) then
          exit
        end if
        cloth(cut_x:cut_x+cut_width-1, cut_y:cut_y+cut_height-1) = &
         cloth(cut_x:cut_x+cut_width-1, cut_y:cut_y+cut_height-1) + 1
      end do
      close(5)

      open (unit=5, file="input.simplified")
      do
        read (5,*,iostat=io_status) id, cut_x, cut_y, cut_width, cut_height
        if (io_status /= 0) exit
        if (sum(cloth(cut_x:cut_x+cut_width-1, cut_y:cut_y+cut_height-1)) == &
         cut_width * cut_height) then
         write(*,*) "Unique ID: ", id
         exit
        end if
      end do
      close(5)

end program aoc32

I don't write a lot of Fortran, and peering at about 7 descriptions of how advanced IO worked didn't get me very far, so I used sed to strip out everything that wasn't a number or a space and that made it much more amenable to Fortran's read input preferences.

 

Woah, this is super cool! The right tool for the right job, huh? 😎 thanks for sharing!

code of conduct - report abuse