@@ 0,0 1,72 @@
+#! /usr/bin/env lua
+--
+-- day05.lua
+-- Copyright (C) 2022 Adrian Perez de Castro <aperez@igalia.com>
+--
+-- Distributed under terms of the MIT license.
+--
+
+-- Contains the lines of input describing the initial contents of the
+-- stacks, to be parsed *after* knowing how many stacks are there.
+local stacks_lines = {}
+
+while true do
+ local line = io.read()
+ if line == "" then
+ break
+ end
+
+ stacks_lines[#stacks_lines+1] = line
+end
+
+-- Last read line contains the numbered stacks, the last number will be
+-- the same as the amount of stacks being handled. Also remove that last
+-- line from the pending-to-parse input.
+local nstacks = 0
+for n in stacks_lines[#stacks_lines]:gmatch("%s*(%d+)%s*") do
+ nstacks = tonumber(n)
+end
+table.remove(stacks_lines)
+
+-- Table where each element is a stack, initially empty.
+local stacks = {}
+for i = 1, nstacks do
+ stacks[i] = {}
+end
+
+-- Parse the stack contents lines backwards, so we get to pile up the
+-- items from the bottom upwards. We can iterate over each found "["
+-- character, and from their position in the line determine in which
+-- stack they are: positions for the opening bracket are always multiples
+-- of four.
+for i = #stacks_lines, 1, -1 do
+ for bracketpos, label in stacks_lines[i]:gmatch("()%[(%a+)%]") do
+ local stacknum = (bracketpos // 4) + 1
+ table.insert(stacks[stacknum], label)
+ end
+end
+
+for line in io.lines() do
+ local _, _, n, from, to = line:find("move (%d+) from (%d+) to (%d+)")
+ local f = stacks[tonumber(from)]
+ local t = stacks[tonumber(to)]
+
+ -- TODO: It should work using table.move(), but somehow it did not.
+ local m = {}
+ for _ = 1, n do
+ m[#m + 1] = table.remove(f)
+ end
+ for i = #m, 1, -1 do
+ table.insert(t, m[i])
+ end
+end
+
+local result = {}
+for i = 1, nstacks do
+ local thisstack = stacks[i]
+ if #thisstack > 0 then
+ result[#result+1] = thisstack[#thisstack]
+ end
+end
+
+print(table.concat(result, ""))