107 lines
2.7 KiB
Julia
107 lines
2.7 KiB
Julia
include("utils.jl")
|
|
|
|
function interval(coords)
|
|
coords[1]:coords[2]
|
|
end
|
|
|
|
function parse_input(filename)
|
|
map(non_empty_lines(filename)) do line
|
|
command, coords = split(line)
|
|
coords = map(x->parse(Int, x.match), eachmatch(r"-?[0-9]+", coords))
|
|
coords = [interval(sort(coords[1:2])),
|
|
interval(sort(coords[3:4])),
|
|
interval(sort(coords[5:6]))]
|
|
command, coords
|
|
end
|
|
end
|
|
|
|
function ccontains(a, b)
|
|
all(issubset.(a, b))
|
|
end
|
|
|
|
function cempty(cube)
|
|
reduce(min, length.(cube)) == 0
|
|
end
|
|
|
|
function setdiffcubes(cube, subcube)
|
|
above = [cube[1], cube[2], (subcube[3].stop+1):(cube[3].stop)]
|
|
below = [cube[1], cube[2], (cube[3].start):(subcube[3].start-1)]
|
|
far = [cube[1], (subcube[2].stop+1):(cube[2].stop), subcube[3]]
|
|
near = [cube[1], (cube[2].start):(subcube[2].start-1), subcube[3]]
|
|
right = [(subcube[1].stop+1):(cube[1].stop), subcube[2], subcube[3]]
|
|
left = [(cube[1].start):(subcube[1].start-1), subcube[2], subcube[3]]
|
|
|
|
filter(c->!cempty(c), [above, below, far, near, right, left])
|
|
end
|
|
|
|
function add_cube(cubes, cube)
|
|
if length(cubes) == 0
|
|
return [cube]
|
|
end
|
|
|
|
if any(map(c->ccontains(cube, c), cubes))
|
|
return cubes
|
|
end
|
|
cubes = filter(c->!ccontains(c, cube), cubes)
|
|
|
|
result = [cube]
|
|
for c in cubes
|
|
inter = intersect.(c, cube)
|
|
if cempty(inter)
|
|
push!(result, c)
|
|
else
|
|
append!(result, setdiffcubes(c, inter))
|
|
end
|
|
end
|
|
result
|
|
end
|
|
|
|
function remove_cube(cubes, cube)
|
|
if length(cubes) == 0
|
|
return []
|
|
end
|
|
result = []
|
|
for c in cubes
|
|
if ccontains(c, cube)
|
|
continue
|
|
end
|
|
inter = intersect.(c, cube)
|
|
if cempty(inter)
|
|
push!(result, c)
|
|
continue
|
|
end
|
|
append!(result, setdiffcubes(c, inter))
|
|
end
|
|
result
|
|
end
|
|
|
|
function magnitude(cube)
|
|
reduce(*, length.(cube))
|
|
end
|
|
|
|
function run(filter=nothing)
|
|
cubes = []
|
|
for (command, coords) in parse_input("22.data")
|
|
if typeof(filter) == Int64 && reduce(max, map(x->reduce(max, abs.(x)), coords)) > filter
|
|
continue
|
|
end
|
|
if command == "on"
|
|
cubes = add_cube(cubes, coords)
|
|
else
|
|
cubes = remove_cube(cubes, coords)
|
|
end
|
|
end
|
|
sum(map(magnitude, cubes))
|
|
end
|
|
|
|
|
|
function solution22_1()
|
|
run(50)
|
|
end
|
|
|
|
function solution22_2()
|
|
run()
|
|
end
|
|
|
|
solution22_1(), solution22_2()
|