109 lines
2.0 KiB
Lua
Executable File
109 lines
2.0 KiB
Lua
Executable File
#!/usr/bin/env luajit
|
|
require("utils")
|
|
|
|
function parse(line)
|
|
local number = {}
|
|
local depth = 0
|
|
for char in chars(line) do
|
|
if char == "[" then
|
|
depth = depth + 1
|
|
elseif char == "]" then
|
|
depth = depth - 1
|
|
elseif char ~= "," then
|
|
table.insert(number, { d=depth, n=tonumber(char) })
|
|
end
|
|
end
|
|
return number
|
|
end
|
|
|
|
function explode(a)
|
|
local new = {}
|
|
local exploded = false
|
|
local i = 1
|
|
while i <= #a do
|
|
if exploded or a[i].d <= 4 then
|
|
table.insert(new, a[i])
|
|
i = i + 1
|
|
else
|
|
exploded = true
|
|
if #new > 0 then
|
|
new[#new].n = new[#new].n + a[i].n
|
|
end
|
|
table.insert(new, { d = a[i].d - 1, n = 0 })
|
|
if #a >= i + 2 then
|
|
table.insert(new, { d = a[i + 2].d, n = a[i + 1].n + a[i + 2].n })
|
|
end
|
|
i = i + 3
|
|
end
|
|
end
|
|
return exploded, new
|
|
end
|
|
|
|
function split(a)
|
|
local new = {}
|
|
local split = false
|
|
for i, digit in ipairs(a) do
|
|
if split or digit.n < 10 then
|
|
table.insert(new, digit)
|
|
else
|
|
split = true
|
|
table.insert(new, { d = digit.d + 1, n = math.floor(digit.n / 2) })
|
|
table.insert(new, { d = digit.d + 1, n = math.ceil(digit.n / 2) })
|
|
end
|
|
end
|
|
return split, new
|
|
end
|
|
|
|
function reduce(a)
|
|
local changed = true
|
|
repeat
|
|
changed, a = explode(a)
|
|
if not changed then
|
|
changed, a = split(a)
|
|
end
|
|
until not changed
|
|
return a
|
|
end
|
|
|
|
function add(a, b)
|
|
local sum = {}
|
|
for i, digit in ipairs(a) do
|
|
table.insert(sum, { d = digit.d + 1, n = digit.n })
|
|
end
|
|
for i, digit in ipairs(b) do
|
|
table.insert(sum, { d = digit.d + 1, n = digit.n })
|
|
end
|
|
return reduce(sum)
|
|
end
|
|
|
|
function magnitude(number)
|
|
local function go(d, c)
|
|
if number[c].d > d then
|
|
local left, right
|
|
left, c = go(d + 1, c)
|
|
right, c = go(d + 1, c)
|
|
return 3 * left + 2 * right, c
|
|
else
|
|
return number[c].n, c + 1
|
|
end
|
|
end
|
|
return go(0, 1)
|
|
end
|
|
|
|
local numbers = {}
|
|
for line in io.lines(arg[3]) do
|
|
table.insert(numbers, parse(line))
|
|
end
|
|
|
|
local max = 0
|
|
for i, a in pairs(numbers) do
|
|
for j, b in pairs(numbers) do
|
|
if i ~= j then
|
|
local m = magnitude(add(a, b))
|
|
if m > max then max = m end
|
|
end
|
|
end
|
|
end
|
|
|
|
print(max)
|