Writing Advent of Code in LifeLab
I thought it would be cool to write and publish the solution for advent of code. I wanted to learn rhai as a an exercise and as a test of LifeLab as a jupyter notebook replacement. Since the data is another block I can directly query, I thought it would be pretty convenient!
Turns out it was not that cool. I had to constantly refer to the rhai book for basic syntax and the autocomplete kinda sucked. That being said, I wonder if I would code similarly in vscode for a language I don't know? I have not learned a new programming language in so long, I am not fully sure how it works, but I am happy to announce I wrote this for loop by myself after learning the syntax which might be the most programming thinking I have done this year.
One other thought I had was how should I reuse code between blocks. In a jupyter notebook you have explicit context (despite not having ordering), here you... kinda do but kidna don't? You can query blocks on this page and you can just import (evaluate) other blocks but it seems clunky to manually manage dependencies.
The original experiment above used Rhai. LifeLab now runs Lua; the runnable example below has been ported to Lua. It keeps the same idea: read rotations from a note, start the dial at 50, and count rotations that end on zero. With the sample input, the answer is 3.
Day 1 — count dial stops at zero (Lua)
3Stops on zero
Start: 50. Count the final position of each rotation; passing zero does not count for part 1.
rotationposition
L6882
L3052
R480
L595
R6055
L550
L199
L990
R1414
L8232
Stops on zero: 3
Show code
-- Advent of Code 2025, day 1, part 1: count rotations ending on zero.
-- The article's original Rhai experiment is now runnable Lua.
local INPUT_BLOCK_ID = "" -- Optional: a block whose content holds one rotation per line.
local input = "L68 L30 R48 L5 R60 L55 L1 L99 R14 L82"
if INPUT_BLOCK_ID ~= "" then
  local source = nb.get_block(INPUT_BLOCK_ID)
  assert(source, "Input block not found")
  input = source.content or ""
end
local position, zeros = 50, 0
local rotations = {}
for instruction in input:gmatch("%S+") do
  local direction, amount = instruction:match("^([LR])(%d+)$")
  assert(direction and amount, "Invalid rotation: " .. instruction)
  local delta = tonumber(amount) * (direction == "L" and -1 or 1)
  position = (position + delta) % 100
  if position == 0 then zeros = zeros + 1 end
  rotations[#rotations + 1] = {rotation=instruction, position=position}
end
ui.column({
  ui.stat("Stops on zero", tostring(zeros)),
  ui.text("Start: 50. Count the final position of each rotation; passing zero does not count for part 1."),
  ui.table(rotations, {columns={"rotation","position"}}),
}, {appearance={gap=2}})
print("Stops on zero: " .. zeros)