Module:User:Cscott/Advent Of Code 2023/Day 1
Appearance
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)()