🇮🇷 Iran Proxy | https://www.wikipedia.org/wiki/Module:User:Cscott/Advent_Of_Code/2024/Day_1
Jump to content

Module:User:Cscott/Advent Of Code/2024/Day 1

From Wikipedia, the free encyclopedia
return (function()
local builders = {}
local function register(name, f)
  builders[name] = f
end
register('advent.compat', function() return require [[Module:User:Cscott/compat]] end)

register('llpeg.lpegrex', function() return require [[Module:User:Cscott/lpegrex]] end)

register('util', function(myrequire)
local function read_wiki_input(func)
    return function (frame, ...)
      if type(frame)=='string' then
        frame = { args = { frame, ... } }
      end
      local title = mw.title.new(frame.args[1])
      local source = title:getContent()
      if source == nil then
        error("Can't find title " .. tostring(title))
      end
      source = source:gsub("^%s*<syntaxhighlight[^>]*>\n?", "", 1)
      source = source:gsub("</syntaxhighlight[^>]*>%s*$", "", 1)
      return func(source, frame.args[2], frame.args[3])
    end
end

return {
  read_wiki_input = read_wiki_input,
}

end)

register('day1', function(myrequire)
--[[
   Day 1, first part; advent of code 2024
]]--

local compat = myrequire('advent.compat')
local lpegrex = myrequire('llpeg.lpegrex')
local read_wiki_input = myrequire('util').read_wiki_input

--[[ PARSING ]]--
local patt = lpegrex.compile([[
Lines <== nl* Line (nl+ Line)* nl*
Line <== {:a: Number :} SKIP {:b: Number :}
Number <-- %d+ -> tonumber
nl <- %nl
SKIP <- [ ]*
NAME_SUFFIX <- [_%w]+
]])

function parse(source)
   --print(inspect(source))
   local ast, errlabel, pos = patt:match(source)
   if not ast then
      local lineno, colno, line = lpegrex.calcline(source, pos)
      local colhelp = string.rep(' ', colno-1)..'^'
      error('syntax error: '..lineno..':'..colno..': '..errlabel..
            '\n'..line..'\n'..colhelp)
   end
   --print('Parsed with success!')
   --print(inspect(ast))
   return ast
end


--[[
   Infrastructure
]]--

function part1(s)
   return day1a(parse(s))
end

function part2(s)
   return day1b(parse(s))
end

--[[
   Part 1
]]--

function day1a(lines)
   local a = {}
   local b = {}
   for i = 1,#lines do
      table.insert(a, lines[i].a)
      table.insert(b, lines[i].b)
   end
   table.sort(a)
   table.sort(b)
   local sum = 0
   for i = 1,#lines do
      local dist = a[i] - b[i]
      if dist < 0 then
	 dist = -dist
      end
      sum = sum + dist
   end
   -- io.write("Sum: ", sum, "\n")
   return sum
end

--[[
Part 2!
]]--

function day1b(lines)
   local a = {}
   local bCount = {}
   for i = 1,#lines do
      table.insert(a, lines[i].a)
      bCount[lines[i].b] = (bCount[lines[i].b] or 0) + 1
   end

   local sum = 0
   for i = 1,#lines do
      sum = sum + a[i] * (bCount[a[i]] or 0)
   end
   -- io.write("Sum: ", sum, "\n")
   return sum
end


--[[
   Testing
]]--

-- io.write("Sum: ", day1a(parse(io.input("day1.example"):read("a"))), "\n")
-- io.write("Sum: ", day1a(parse(io.input("day1.input"):read("a"))), "\n")

-- io.write("Similarity: ", day1b(parse(io.input("day1.example"):read("a"))), "\n")
-- io.write("Similarity: ", day1b(parse(io.input("day1.input"):read("a"))), "\n")

return {
   part1 = read_wiki_input(part1),
   part2 = read_wiki_input(part2),
}

end)

local modules = {}
modules['bit32'] = require('bit32')
modules['string'] = require('string')
modules['strict'] = {}
modules['table'] = require('table')
local function myrequire(name)
  if modules[name] == nil then
    modules[name] = true
    modules[name] = (builders[name])(myrequire)
  end
  return modules[name]
end
return myrequire('day1')
end)()