-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path22.py
executable file
·73 lines (61 loc) · 1.79 KB
/
22.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3
from __future__ import annotations
import itertools as it
from typing import List, NamedTuple
with open("data/22.txt") as f:
lines = f.readlines()
def parse(line):
mode, coords = line.split(" ")
xstr, ystr, zstr = coords.split(",")
return mode, tuple(
[int(x) for x in s[2:].split("..")]
for s in coords.split(",")
)
# Part 1
# def start_range(l, r):
# return range(max(l, -50), min(r, 50) + 1)
#
# on = set()
# for line in lines:
# mode, (xs, ys, zs) = parse(line)
# coords = set(it.product(start_range(*xs), start_range(*ys), start_range(*zs)))
# if mode == "on":
# on |= coords
# else:
# on -= coords
#
# print(len(on))
# Part 2 would be a bit too memory hungry.
class Range(NamedTuple):
""" Half-open so we can easily determine size.
Manually ensure left <= right.
"""
left: int
right: int
def __len__(self) -> int:
return self.right - self.left
def overlap(self, other: Range) -> Range:
l = max(self.left, other.left)
r = min(self.right, other.right)
if l > r:
return Range(0, 0)
return Range(l, r)
assert len(Range(0, 10)) == 10
assert len(Range(1, 10)) == 9
assert Range(0, 100).overlap(Range(0, 100)) == Range(0, 100)
assert Range(1, 100).overlap(Range(0, 100)) == Range(1, 100)
assert Range(0, 100).overlap(Range(0, 99)) == Range(0, 99)
class Cuboid(NamedTuple):
x: Range
y: Range
z: Range
def union(self, other: Cuboid) -> List[Cuboid]:
xo = self.x.overlap(other.x)
if len(xo) == 0:
return [self, other]
yo = self.y.overlap(other.y)
if len(yo) == 0:
return [self, other]
zo = self.z.overlap(other.z)
if len(zo) == 0:
return [self, other]