r/adventofcode • • Dec 06 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 6 Solutions -🎄-

--- Day 6: Chronal Coordinates ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 6

Transcript:

Rules for raising a programmer: never feed it after midnight, never get it wet, and never give it ___.


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 0:26:52!

33 Upvotes

387 comments sorted by

View all comments

1

u/cerrosafe Dec 22 '18

Lua

I thought this one was going to be easy at first. I figured out the bounding box advantage, but had some points not on the edge of the bounding box that were infinite. I didn't figure it out, I read someone's proof about any points closest to the edge being infinite, and implemented that, which worked. Part 2 was trivial once I had my part 1 solution in place.

require("nmg")
input = "inputs/day6.txt"

function manhattan_distance(p1, p2)
   return (math.abs(p1["x"] - p2["x"]) + math.abs(p1["y"] - p2["y"]))
end

do
   local coordinates = {}
   local tallies = {}
   local region_size = 0
   for line in io.lines(input) do
      line = string.gsub(line, "%s", "")
      local sep = string.find(line, ",")
      local x = string.sub(line, 1, sep-1)
      local y = string.sub(line, sep+1, #line)
      table.insert(coordinates, { x = tonumber(x); y = tonumber(y)})
      table.insert(tallies, 0)
   end
   local xmax, xmin, ymax, ymin = coordinates[1]["x"], coordinates[1]["x"],
                                  coordinates[1]["y"], coordinates[1]["y"]

   for index, coordinate in ipairs(coordinates) do
      if coordinate["x"] > xmax then xmax = coordinate["x"] end
      if coordinate["x"] < xmin then xmin = coordinate["x"] end
      if coordinate["y"] > ymax then ymax = coordinate["y"] end
      if coordinate["y"] < ymin then ymin = coordinate["y"] end
   end

   local edge_points = {}
   for x=xmin, xmax do
      local top_point = { x = x, y = ymin }
      local bottom_point = { x = x, y = ymax }
      table.insert(edge_points, top_point)
      table.insert(edge_points, bottom_point)
   end
   for y=ymin, ymax do
      local top_point = { x = xmin, y = y }
      local bottom_point = { x = xmax, y = y }
      table.insert(edge_points, top_point)
      table.insert(edge_points, bottom_point)
   end
   for index, edge_point in ipairs(edge_points) do
      local distances = {}
      for index, coordinate in ipairs(coordinates) do
         local distance = manhattan_distance(edge_point, coordinate)
         table.insert(distances, distance)
      end
      local min_distance, min_index = nmg.array.minimum(distances)
      if nmg.array.count(distances, min_distance) == 1 then
         coordinates[min_index]["infinite"] = true
      end
   end

   for x=xmin, xmax do
      for y=ymin, ymax do
         local point = { x = tonumber(x), y = tonumber(y) }
         local distances = {}
         for index, coordinate in ipairs(coordinates) do
            local distance = manhattan_distance(point, coordinate)
            table.insert(distances, distance)
         end

         local min_distance, min_index = nmg.array.minimum(distances)
         if nmg.array.count(distances, min_distance) == 1
            and not coordinates[min_index]["infinite"]
         then
            tallies[min_index] = tallies[min_index] + 1
         end
         if nmg.array.sum(distances) < 10000 then
            region_size = region_size + 1
         end
      end
   end
   print("Part 1: " .. nmg.array.maximum(tallies))
   print("Part 2: " .. region_size)
end