aoc2021/18.jl

136 lines
2.7 KiB
Julia

include("utils.jl")
function parse_value(line, index)
if line[index] == '['
parse_tuple(line, index)
else
digits = match(r"^[0-9]+", SubString(line, index)).match
index += length(digits)
parse(Int, digits), index
end
end
function parse_tuple(line, index=1)
@assert line[index] == '['
index += 1
first, index = parse_value(line, index)
@assert line[index] == ','
index += 1
second, index = parse_value(line, index)
@assert line[index] == ']'
index +=1
return Any[first, second], index
end
function parse_input(filename)
map(x->x[1], map(parse_tuple, non_empty_lines(filename)))
end
function split_sf(a)
if typeof(a) == Int64
if a > 9
Any[div(a,2),div(a,2)+rem(a,2)], true
else
a, false
end
else
l, changed = split_sf(a[1])
a[1] = l
if changed
a, true
else
r, changed = split_sf(a[2])
a[2] = r
a, changed
end
end
end
function add_left_sf(a, number)
if typeof(a) == Int64
a + number
else
a[1] = add_left_sf(a[1], number)
a
end
end
function add_right_sf(a, number)
if typeof(a) == Int64
a + number
else
a[2] = add_right_sf(a[2], number)
a
end
end
function explode_sf(a, level=1)
if typeof(a) == Int64
return a, false, 0, 0
end
if level == 5
@assert typeof(a[1]) == Int64 && typeof(a[2]) == Int64
0, true, a[1], a[2]
else
l, changed, to_left, to_right = explode_sf(a[1], level + 1)
if changed
Any[l, add_left_sf(a[2], to_right)], true, to_left, 0
else
r, changed, to_left, to_right = explode_sf(a[2], level + 1)
if changed
Any[add_right_sf(l, to_left), r], true, 0, to_right
else
a, false, 0, 0
end
end
end
end
function reduce_sf(a)
changed = true
while changed
a, changed = explode_sf(a)
if changed
continue
end
a, changed = split_sf(a)
end
a
end
function add_sf(a, b)
reduce_sf(Any[deepcopy(a), deepcopy(b)])
end
function mag_sf(a)
if typeof(a) == Int64
a
else
3 * mag_sf(a[1]) + 2 * mag_sf(a[2])
end
end
function solution18_1()
mag_sf(reduce(add_sf, parse_input("18.data")))
end
function solution18_2()
input = collect(parse_input("18.data"))
max_mag = 0
for a in input
for b in input
print('.')
max_mag = max(max_mag, mag_sf(add_sf(a, b)))
end
end
println("")
max_mag
end
solution18_2()