Parcourir la source

distance

master
Roderic Day il y a 3 ans
Parent
révision
9f7d21d01a
1 fichiers modifiés avec 31 ajouts et 54 suppressions
  1. +31
    -54
      y2021/p22.py

+ 31
- 54
y2021/p22.py Voir le fichier

@@ -1,57 +1,34 @@
import re


def intersect(cube, other):
return not (
cube[1] <= other[0] or
cube[0] >= other[1] or
cube[3] <= other[2] or
cube[2] >= other[3] or
cube[5] <= other[4] or
cube[4] >= other[5]
)


def insert(cube, val):
to_break = {other for other in seen if intersect(cube, other)}
for cu in to_break:
seen.discard(cu)

xAs, xBs, yAs, yBs, zAs, zBs = zip(*{cube} | to_break)
xs = sorted(set(xAs + xBs))
ys = sorted(set(yAs + yBs))
zs = sorted(set(zAs + zBs))
N = 0
for i in range(len(xs) - 1):
for j in range(len(ys) - 1):
for k in range(len(zs) - 1):
new = (xs[i], xs[i + 1], ys[j], ys[j + 1], zs[k], zs[k + 1])

if val == 'off' and intersect(new, cube):
seen.discard(new)

elif val == 'on' and intersect(new, cube):
seen.add(new)

elif any(intersect(old, new) for old in to_break):
seen.add(new)


def volume(xA, xB, yA, yB, zA, zB):
return abs(xB - xA) * abs(yB - yA) * abs(zB - zA)


text = open(0).read()
cubes = {}
for line in text.splitlines():
val = line.split()[0]
xA, xB, yA, yB, zA, zB = [int(n) for n in re.findall(r'-?\d+', line)]
cubes[xA, xB + 1, yA, yB + 1, zA, zB + 1] = val


seen = set()
for i, (cube, val) in enumerate(cubes.items(), 1):
insert(cube, val)
if i == 20:
print(sum(volume(*cu) for cu in seen))
print(sum(volume(*cu) for cu in seen))
def net_volume(cubes):
if not cubes:
return 0

(is_on, cube), *rest = cubes
if not is_on:
return net_volume(rest)

return volume(cube) - net_volume(intersect(cube, rest)) + net_volume(rest)


def intersect(cube, rest):
return [
(True, new)
for _, other in rest
for new in [[f(a, b) for a, b, f in zip(cube, other, [max, min] * 3)]]
if volume(new)
]


def volume(cube):
xA, xB, yA, yB, zA, zB = cube
return max(xB - xA + 1, 0) * max(yB - yA + 1, 0) * max(zB - zA + 1, 0)


cubes = tuple(
(line.split()[0] == 'on', [int(n) for n in re.findall(r'-?\d+', line)])
for line in open(0).read().splitlines()
)
print(net_volume(cubes[:20]))
print(net_volume(cubes))

Chargement…
Annuler
Enregistrer