return (functionlocal builders = local function register(name, f) builders[name] = fendregister('llpeg', function return require end)
register('day15', function(myrequire)--DAY 15 --local lpeg = myrequire('llpeg')
--PARSING --function split (s, sep) sep = lpeg.P(sep) local elem = lpeg.C((1 - sep)^0) local p = lpeg.Ct(elem * (sep * elem)^0) -- make a table capture return lpeg.match(p, s)end
function parse1(s) s = s:gsub("\n", "") return split(s, ",")end
function hash(s) local currentValue = 0 for _,ascii in ipairs do currentValue = currentValue + ascii currentValue = currentValue * 17 currentValue = currentValue % 256 end return currentValueend
function part1(s) local sum = 0 for _,ss in ipairs(parse1(s)) do sum = sum + hash(ss) end return sumend
--PART 2 --local l = lpeglocal nl = l.P"\n"local patt = l.P
function parse2(source) source = source:gsub("\n", "") --print(inspect(source)) local ast, errlabel, pos = patt:match(source) if not ast then error(string.format("Error at pos %s label '%s'", pos, errlabel)) end --print('Parsed with success!') --print(inspect(ast)) return astend
local Lens = Lens.__index = Lensfunction Lens:new(props) return setmetatable(props or, self)end
local Box = Box.__index = Boxfunction Box:new return setmetatable(self)endfunction Box:get(label) return self.lensMap[label]endfunction Box:addLens(label, lens) table.insert(self.lensList, lens) lens.pos = #(self.lensList) self.lensMap[label] = lensendfunction Box:remove(label) local old = self:get(label) old.focalLen = nil -- tombstone self.lensMap[label] = nil -- removeendfunction Box:sum(mult) local i = 1 local sum = 0 for _,l in ipairs(self.lensList) do if l.focalLen ~= nil then sum = sum + (mult * i * l.focalLen) i = i + 1 end end return sumend
local Hashmap = Hashmap.__index = Hashmap;
function Hashmap:new(s) return setmetatable(s or, self)end
function Hashmap:getBox(i) local box = self[i+1] if box
function Hashmap:execute(op) if op.dash then self:executeDash(op) else self:executeEq(op) endend
function Hashmap:executeDash(op) local box = self:getBox(op.hash) local old = box:get(op.label) if old ~= nil then box:remove(op.label) endend
function Hashmap:executeEq(op) local box = self:getBox(op.hash) local old = box:get(op.label) if old ~= nil then -- already a lens with this label, replace it old.focalLen = op.focalLen else local lens = Lens:new box:addLens(op.label, lens) endend
function Hashmap:sum local sum = 0 for i=0,255 do local box = self:getBox(i) sum = sum + box:sum(i+1) end return sumend
function part2(source) local h = Hashmap:new local ops = parse2(source) for i=1,#ops do h:execute(ops[i]) end return h:sumend
--CLI ]--local source = io.input("day15.input"):read("*a")print('Sum:', part1(source))print('Sum:', part2(source))--[[ END CLI ]]--
return
end)
local modules = modules['table'] = require('table')modules['string'] = require('string')modules['strict'] = local function myrequire(name) if modules[name]