return (functionlocal builders = local function register(name, f) builders[name] = fendregister('llpeg', function return require end)
register('day12', function(myrequire)--DAY 12 --local l = myrequire('llpeg')
--PARSING --
local SKIP = l.P" " ^ 0local nl = l.P"\n"
local patt = l.P
function parse(source) --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
--Part 1 --
local State = State.__index = Statefunction State:new return setmetatable(State)endfunction State:update(props) for k,v in pairs(self) do if props[k]
function State:key local i = 0 if self.in_group then i = 1 end return string.format("%d %d %d %d", self.spring_index, self.cond_index, i, self.group_size)end
function State:__tostring local group_status = "" if self.in_group then group_status = string.format(" in group of size %d", self.group_size) end return string.format("%d spring=%d condition=%d%s", self.count, self.spring_index, self.cond_index, group_status)end
function State:operational(condlist) if self.in_group then -- going to leave group if self.group_size ~= condlist[self.cond_index] then return nil -- this doesn't work end return self:update else return self:update endend
function State:damaged(condlist) if self.in_group then local new_group_size = self.group_size + 1 if new_group_size > condlist[self.cond_index] then return nil -- this doesn't work end return self:update else if self.cond_index > #condlist then return nil -- this doesn't work end return self:update endend
function State:done(springs) return self.spring_index > #springsend
function State:finalize(condlist) --print("Finalizing",self) local cond_index = self.cond_index if self.in_group then if self.group_size ~= condlist[cond_index] then return 0 -- this doesn't work end cond_index = cond_index + 1 end if cond_index ~= (#condlist + 1) then return 0 -- not enough groups end return self.count -- how many ways to make this stateend
function count_ways(springs, condlist) local state = State:new local seen = local todo = local function insert_new_state(nstate) if nstate ~= nil then local nkey = nstate:key if seen[nkey]
"." or spring
"#" or spring
function part1(source) local lines = parse(source) local sum = 0 -- print(inspect(lines)) for i=1,#lines do local ways = count_ways(lines[i].springs, lines[i].condlist) --print(i, ways) sum = sum + ways end return sumend
--Part 2 --
function expand(line) local nsprings = local ncond = for i = 1,5 do for _,v in ipairs(line.springs) do table.insert(nsprings, v) end if i < 5 then table.insert(nsprings, "?") end for _,v in ipairs(line.condlist) do table.insert(ncond, v) end end return end
function part2(source) local lines = parse(source) local sum = 0 for i,line in ipairs(lines) do line = expand(line) -- print(inspect(line)) local ways = count_ways(line.springs, line.condlist) --print(i, ways) sum = sum + ways end return sumend
--CLI ]--local source = io.input("day12.input"):read("a")print("Part 1 sum:", part1(source))print("Part 2 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]