-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathd03.py
More file actions
72 lines (51 loc) · 1.92 KB
/
d03.py
File metadata and controls
72 lines (51 loc) · 1.92 KB
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
from dataclasses import dataclass
import re
from typing import Counter, Dict, List, Tuple
from day import Day, register_day
@register_day(2018, 3)
class Day03(Day):
def part_one(self) -> str:
claims = parse_input(self.read_input())
claims_points = []
for c in claims:
for cp in c.area():
claims_points.append(cp)
res = len([k for k, v in Counter(claims_points).items() if v >= 2])
return str(res)
def part_two(self) -> str:
claims = parse_input(self.read_input())
points_map: Dict[Tuple[int, int], List[int]] = dict()
intersect = []
claim_ids = [c.identifier for c in claims]
for c in claims:
for cp in c.area():
if points_map.get(cp) is not None:
points_map[cp].append(c.identifier)
intersect.extend(points_map[cp])
else:
points_map[cp] = [c.identifier]
res = set(claim_ids) - set(intersect)
return str(res.pop())
# -----------------------------------------------------------------------------
claim_pattern = re.compile(r"#(\d+)\s@\s(\d+,\d+):\s(\d+x\d+)")
@dataclass
class Claim:
identifier: int
starting_pos: Tuple[int, int]
size: Tuple[int, int]
def area(self) -> List[Tuple[int, int]]:
taken = []
x = self.starting_pos[0]
y = self.starting_pos[1]
for yi in range(0, self.size[1]):
for xi in range(0, self.size[0]):
taken.append((x + xi, y + yi))
return taken
def parse_input(input_data: str) -> List[Claim]:
claims = []
claims_raw = claim_pattern.findall(input_data)
for rc in claims_raw:
pos = list(map(lambda x: int(x), rc[1].split(",")))
size = list(map(lambda x: int(x), rc[2].split("x")))
claims.append(Claim(int(rc[0]), (pos[0], pos[1]), (size[0], size[1])))
return claims