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