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

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('day1', function(myrequire) --  Day 1, first part; advent of code 2023 --

local compat = myrequire('advent.compat')

--  Infrastructure --

function split(str) lines = {} for s in string.gmatch(str, "[^\r\n]+") do     table.insert(lines, s)   end return lines end

function part1(frame) local s = mw.title.new(frame.args[1]):getContent return day1a(split(s)) end

function part2(frame) local s = mw.title.new(frame.args[1]):getContent return day1b(split(s)) end

--  Part 1 --

function day1a(lines) local sum = 0 for _,line in pairs(lines) do     -- ignore everything but numbers local nums = string.gsub(line, "[^0-9]", "") -- ignore everything but the first and the last nums = string.sub(nums, 1, 1) .. string.sub(nums, -1, -1) -- coerce to integer n = 0 + nums sum = sum + n     -- io.write(n, "\n") end -- io.write("Sum: ", sum, "\n") return sum end

-- Part 2! --

local digits = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }

function findDigit(str) for d = 1, #digits do     local word = digits[d] -- io.write("checking ",word,"\n") if string.sub(str, 1, #word) == word then return d, #word end end -- is the first character a digit? if string.match(str, "^[0-9]") then return (0 + string.sub(str, 1, 1)), 1 else return 0, 0 end end

function day1b(lines) local sum = 0 for _,line in pairs(lines) do     local first local last -- find first digit i = 1 while i <= #line do        local piece = string.sub(line, i)         d, len = findDigit(piece) if len > 0 then first = d           break else -- ignore this character i = i + 1 end end -- find last digit i = #line while i >= 1 do        local piece = string.sub(line, i)         d, len = findDigit(piece) if len > 0 then last = d           break else -- ignore this character i = i - 1 end end -- ignore everything but the first and the last digit local n = (10*first) + last -- io.write(line, " -> ", n, "\n") sum = sum + n  end return sum end

--  Testing --

-- io.write("Sum: ", day1a(io.lines(compat.unpack(arg))), "\n") -- io.write("Sum: ", day1a(split(io.input("day1.example"):read("a"))), "\n")

-- io.write("Sum: ", day1b(split(io.input("day1b.example"):read("a"))), "\n")

return { part1 = part1, part2 = 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)