136 lines
2.7 KiB
Julia
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()
|