選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

58 行
1.5KB

  1. import re
  2. def intersect(cube, other):
  3. return not (
  4. cube[1] <= other[0] or
  5. cube[0] >= other[1] or
  6. cube[3] <= other[2] or
  7. cube[2] >= other[3] or
  8. cube[5] <= other[4] or
  9. cube[4] >= other[5]
  10. )
  11. def insert(cube, val):
  12. to_break = {other for other in seen if intersect(cube, other)}
  13. for cu in to_break:
  14. seen.discard(cu)
  15. xAs, xBs, yAs, yBs, zAs, zBs = zip(*{cube} | to_break)
  16. xs = sorted(set(xAs + xBs))
  17. ys = sorted(set(yAs + yBs))
  18. zs = sorted(set(zAs + zBs))
  19. N = 0
  20. for i in range(len(xs) - 1):
  21. for j in range(len(ys) - 1):
  22. for k in range(len(zs) - 1):
  23. new = (xs[i], xs[i + 1], ys[j], ys[j + 1], zs[k], zs[k + 1])
  24. if val == 'off' and intersect(new, cube):
  25. seen.discard(new)
  26. elif val == 'on' and intersect(new, cube):
  27. seen.add(new)
  28. elif any(intersect(old, new) for old in to_break):
  29. seen.add(new)
  30. def volume(xA, xB, yA, yB, zA, zB):
  31. return abs(xB - xA) * abs(yB - yA) * abs(zB - zA)
  32. text = open(0).read()
  33. cubes = {}
  34. for line in text.splitlines():
  35. val = line.split()[0]
  36. xA, xB, yA, yB, zA, zB = [int(n) for n in re.findall(r'-?\d+', line)]
  37. cubes[xA, xB + 1, yA, yB + 1, zA, zB + 1] = val
  38. seen = set()
  39. for i, (cube, val) in enumerate(cubes.items(), 1):
  40. insert(cube, val)
  41. if i == 20:
  42. print(sum(volume(*cu) for cu in seen))
  43. print(sum(volume(*cu) for cu in seen))