DEV Community

Discussion on: AoC Day 6: Chronal Coordinates

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I doubt this is the most performant solution, but it gets the job done for smaller sets of input data.

-- Set up some stuff

local inf = math.abs(1/0)

local point = {
  __tostring = function(self)
    return string.format("(%03i, %03i)", self[1], self[2])
  end
}

-- First of all, read in all the points.
-- This is just some boring I/O, and integer parsing.
local points = {}
for line in io.stdin:lines() do
  local point = setmetatable({}, point)
  for coordinate in line:gmatch('%d+') do
    table.insert(point, tonumber(coordinate))
  end
  table.insert(points, point)
end

-- Find smallest axis-aligned rectangle (R) that contains all points

local min_x, max_x, min_y, max_y = inf, 0, inf, 0
for _,point in ipairs(points) do
  local x, y = point[1], point[2]
  min_x = math.min(x, min_x)
  min_y = math.min(y, min_y)
  max_x = math.max(x, max_x)
  max_y = math.max(y, max_y)
end

-- Helper function that finds the nearest input point given two coordinates.

local function nearest(x, y)
  local dist, point = inf
  local mid = false
  for _,p in ipairs(points) do
    local d = (math.abs(x-p[1]) + math.abs(y-p[2]))
    if d == dist then
      mid = true
    elseif d < dist then
      mid = false
      dist = d
      point = p
    end
  end
  return (not mid) and point
end

-- Mapping points to their respective counts:
-- Iterate all points in R, find the nearest input point and add 1 to its count.

local counts = {}
for y = min_y, max_y do
  for x = min_x, max_x do
    local nearest = nearest(x, y)
    if nearest then
      if y==min_y or y==max_y or x==max_x or x==min_x then
        counts[nearest] = -inf
      else
        counts[nearest] = (counts[nearest] or 0) + 1
      end
    end
  end
end

-- Iterate all point-count pairs and remember the highest count; this is our answer.

local highest = 0
for point, count in pairs(counts) do
  print(point, count)
  highest = math.max(count, highest)
end

-- Output the answer and be happy about it :)

print(highest)