#!/usr/bin/env luajit require("utils") local function r(s, e) -- Upper borders are exclusive here! return { s=s, e=e } end local ranges = {} for line in io.lines(arg[3]) do local b, x0, x1, y0, y1, z0, z1 = line:match("(.*) x=(.*)%.%.(.*),y=(.*)%.%.(.*),z=(.*)%.%.(.*)") if b == "on" then b = true else b = false end table.insert(ranges, { b=b, x=r(tonumber(x0), tonumber(x1) + 1), y=r(tonumber(y0), tonumber(y1) + 1), z=r(tonumber(z0), tonumber(z1) + 1), }) end local function intersect1d(a, b) if a.e <= b.s or b.e <= a.s then -- aaa bbb -- bbb aaa return { a }, {}, { b } elseif a.s <= b.s and b.s <= a.e and a.e <= b.e then -- aaa222bbb return { r(a.s, b.s) }, { r(b.s, a.e) }, { r(a.e, b.e) } elseif a.s <= b.s and b.e <= a.e then -- aaa222aaa return { r(a.s, b.s), r(b.e, a.e) }, { b }, {} elseif b.s <= a.s and a.e <= b.e then -- bbb222bbb return {}, { a }, { r(b.s, a.s), r(a.e, b.e) } elseif b.s <= a.s and b.e <= a.e then -- bbb222aaa return { r(b.e, a.e) }, { r(a.s, b.e) }, { r(b.s, a.s) } else error("unreachable?") end end local function cut3d(a, b) local aparts = {} local xas, xabs, xbs = intersect1d(a.x, b.x) local yas, yabs, ybs = intersect1d(a.y, b.y) local zas, zabs, zbs = intersect1d(a.z, b.z) local nobscombos = { { xas, yas, zas } , { xas, yas, zabs } , { xas, yabs, zas } , { xas, yabs, zabs } , { xabs, yas, zas } , { xabs, yas, zabs } , { xabs, yabs, zas } } for _, combo in pairs(nobscombos) do local xs, ys, zs = unpack(combo) for _, x in pairs(xs) do if x.s < x.e then for _, y in pairs(ys) do if y.s < y.e then for _, z in pairs(zs) do if z.s < z.e then table.insert(aparts, { b = a.b, x=x, y=y, z=z }) end end end end end end end return aparts end local count = 0 for i = 1, #ranges do if ranges[i].b then print(i, os.clock()) local fixed = { ranges[i] } for j = i + 1, #ranges do local newfixed = {} for _, f in pairs(fixed) do for _, fpart in pairs(cut3d(f, ranges[j])) do table.insert(newfixed, fpart) end end fixed = newfixed end for _, r in pairs(fixed) do -- printtable(r) count = count + (r.x.e - r.x.s)*(r.y.e - r.y.s)*(r.z.e - r.z.s) end end end io.write(string.format("%d\n", count))