return (functionlocal builders = local function register(name, f) builders[name] = fendregister('advent.compat', function return require end)
register('day3', function(myrequire)--Day 1, first part; advent of code 2023--
local compat = myrequire('advent.compat')--local inspect = require 'inspect'
--Infrastructure--
function split(str) lines = for s in string.gmatch(str, "[^\r\n]+") do table.insert(lines, s) end return linesend
function part1(frame) local s = frame:expandTemplate return day1a(split(s))end
function part2(frame) local s = frame:expandTemplate return day1b(split(s))end
--Part 1--
function make_graph(lines) local graph = for row = 1,#lines do local l = lines[row] graph[row] = for col = 1,#l do graph[row][col] = l:sub(col, col) end end return graph, #graph, #(graph[1])end
function is_symbol(c) return c:match("[0-9.]")
nil)endfunction char_at(graph, row, col) if row < 1 then return "." elseif row > #graph then return "." end r = graph[row] if col < 1 then return "." elseif col > #r then return "." end return r[col]end
function symbol_around(graph, row, col) for r = row-1, row+1 do for c = col-1, col+1 do if is_symbol(char_at(graph, r, c)) then return true end end end return falseend
function day1a(lines) local graph, rows, cols = make_graph(lines) -- look for numbers local in_number = false local seen_symbol = false local seen_number = "" local sum = 0 for row = 1, rows do for col = 1, cols do local c = graph[row][col] if in_number then if is_digit(c) then -- continue our number seen_number = seen_number .. c seen_symbol = seen_symbol or symbol_around(graph, row, col) else -- finish our number --print("Found", seen_number, seen_symbol) in_number = false if seen_symbol then local n = 0 + seen_number -- coerce to int sum = sum + n end end else -- not in_number, see if we want to start one if is_digit(c) then in_number = true seen_number = c seen_symbol = symbol_around(graph, row, col) end end end end return sumend
--Part 2!--
function gears_around(graph, row, col) gears = for r = row-1, row+1 do for c = col-1, col+1 do if char_at(graph, r, c)
nil then gears[r] = end gears[r][c] = true end end end return gearsend
function day1b(lines) local graph, rows, cols = make_graph(lines) -- look for numbers local in_number = false local seen_gears = local seen_number = "" local number_for_gear =
for row = 1, rows do for col = 1, cols do local c = graph[row][col] if in_number then if is_digit(c) then -- continue our number seen_number = seen_number .. c for r,row in pairs(gears_around(graph, row, col)) do for c,_ in pairs(row) do if seen_gears[r]
nil then number_for_gear[r] = end if number_for_gear[r][c]
2 then sum = sum + (nums[1] * nums[2]) end end end return sumend
--Testing--
--print(inspect(day1a(split(io.input("day3.example"):read("a")))))--print(inspect(day1a(split(io.input("day3.input"):read("a")))))
--print(inspect(day1b(split(io.input("day3.example"):read("a")))))--print(inspect(day1b(split(io.input("day3.input"):read("a")))))
return
end)
local modules = modules['table'] = require('table')modules['string'] = require('string')modules['strict'] = local function myrequire(name) if modules[name]