DEV Community

Discussion on: AoC Day 3: No Matter How You Slice It

Collapse
ikirker profile image
Ian Kirker • Edited on

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.

Collapse
rpalo profile image
Ryan Palo Author

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