Module:User:Cscott/Advent Of Code 2023/Day 9 Explained

return (functionlocal builders = local function register(name, f) builders[name] = fendregister('llpeg', function return require end)

register('day9', function(myrequire)--DAY 9 --local l = myrequire('llpeg')-- local inspect = require 'inspect'

--PARSING --

local SKIP = l.P" " ^ 0local nl = l.P"\n"function tok(s) return l.P(s) * SKIP end

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 --

function predict_next(seq) local diffs = local saw_nonzero = false for i=2,#seq do local d = (seq[i] - seq[i-1]) table.insert(diffs, d) if seq[i] ~= 0 then saw_nonzero = true end end if saw_nonzero then table.insert(diffs, predict_next(diffs)) -- now compute the next value return seq[#seq] + diffs[#diffs] else -- easy: the sequence was all zeros so predict a zero! return 0 endend

function part1(source) local lines = parse(source) local sum = 0 for i=1,#lines do local seq = lines[i] local prediction = predict_next(seq) -- print(inspect(seq), prediction) sum = sum + prediction end return sumend

--Part 2 --

function predict_prev_and_next(seq) local diffs = local saw_nonzero = false for i=2,#seq do local d = (seq[i] - seq[i-1]) table.insert(diffs, d) if seq[i] ~= 0 then saw_nonzero = true end end if saw_nonzero then local p, n = predict_prev_and_next(diffs) -- compute the previous value local prev = seq[1] - p -- now compute the next value local nxt = seq[#seq] + n return prev,nxt else -- easy: the sequence was all zeros so predict a zero (on both sides)! return 0,0 endend

function part2(source) local lines = parse(source) local sum = 0 for i=1,#lines do local seq = lines[i] local p,n = predict_prev_and_next(seq) -- print(p, inspect(seq), n) sum = sum + p end return sumend

----

return

end)

local modules = modules['table'] = require('table')modules['string'] = require('string')modules['strict'] = local function myrequire(name) if modules[name]