1+ #!/usr/bin/env python
2+ # -*- coding: utf-8 -*-
3+
4+ from itertools import combinations
5+
6+ def parse (data ):
7+ ants = {}
8+ bounds = len (data .split ('\n ' )[0 ]), len (data .split ('\n ' ))
9+ for y , line in enumerate (data .split ('\n ' )):
10+ for x , char in enumerate (line ):
11+ if char == '.' : continue
12+ if char not in ants : ants [char ] = []
13+ ants [char ].append ((x , y ))
14+
15+ return ants , bounds
16+
17+ split_data = parse
18+ completed = True
19+ raw_data = None # Not To be touched
20+
21+ def part1 (data ):
22+ # Wow, this is pure math...
23+ ants , bounds = data
24+ antiNodes = set ()
25+ for nodes in ants .values ():
26+
27+ for (a1x , a1y ), (a2x , a2y ) in combinations (nodes , r = 2 ):
28+ dx , dy = a2x - a1x , a2y - a1y
29+ anti1 = (a1x - dx , a1y - dy )
30+ anti2 = (a2x + dx , a2y + dy )
31+
32+ if 0 <= anti1 [0 ] < bounds [0 ] and 0 <= anti1 [1 ] < bounds [1 ]:
33+ antiNodes .add (anti1 )
34+ if 0 <= anti2 [0 ] < bounds [0 ] and 0 <= anti2 [1 ] < bounds [1 ]:
35+ antiNodes .add (anti2 )
36+
37+ return len (antiNodes )
38+
39+ def part2 (data ):
40+ ants , bounds = data
41+ antiNodes = set ()
42+ for nodes in ants .values ():
43+
44+ for (a1x , a1y ), (a2x , a2y ) in combinations (nodes , r = 2 ):
45+ dx , dy = a2x - a1x , a2y - a1y
46+
47+ nx , ny = a1x , a1y
48+ while 0 <= nx < bounds [0 ] and 0 <= ny < bounds [1 ]:
49+ antiNodes .add ((nx , ny ))
50+ nx -= dx
51+ ny -= dy
52+
53+ nx , ny = a1x , a1y
54+ while 0 <= nx < bounds [0 ] and 0 <= ny < bounds [1 ]:
55+ antiNodes .add ((nx , ny ))
56+ nx += dx
57+ ny += dy
58+
59+ return len (antiNodes )
0 commit comments