1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ def parse (data ):
5
+ elves = []
6
+
7
+ for y , line in enumerate (data .split ('\n ' )):
8
+ for x , chr in enumerate (line ):
9
+ if chr != '#' : continue
10
+ elves .append ((x , y ))
11
+
12
+ return elves
13
+
14
+ split_data = parse
15
+ completed = True
16
+ raw_data = None # Not To be touched
17
+
18
+ def part1 (data ):
19
+ def empty (check , point ):
20
+ return all ((point [0 ]+ dx , point [1 ]+ dy ) not in data for dx , dy in check )
21
+
22
+
23
+ north = [(- 1 , - 1 ), ( 0 , - 1 ), ( 1 , - 1 )] # NW, N, NE
24
+ south = [(- 1 , 1 ), ( 0 , 1 ), ( 1 , 1 )] # SW, S, SE
25
+ west = [(- 1 , - 1 ), (- 1 , 0 ), (- 1 , 1 )] # NW, W, SW
26
+ east = [( 1 , - 1 ), ( 1 , 0 ), ( 1 , 1 )] # NE, E, SE
27
+ allD = [(dx , dy ) for dy in range (- 1 , 2 ) for dx in range (- 1 , 2 ) if (dx , dy ) != (0 , 0 )]
28
+
29
+ checks = [north , south , west , east ]
30
+
31
+ for _ in range (10 ):
32
+ print ('Simulation Step:' ,_ + 1 )
33
+ propositions = {}
34
+
35
+ for elve in data :
36
+ if empty (allD , elve ): # No move
37
+ propositions [elve ] = [elve ]
38
+ continue
39
+
40
+ for check in checks :
41
+ if empty (check , elve ):
42
+ # print(f'Found a valid check for {elve} elve: {check[1]}')
43
+ px , py = elve [0 ]+ check [1 ][0 ], elve [1 ]+ check [1 ][1 ]
44
+ propositions [(px , py )] = propositions .get ((px , py ), []) + [elve ]
45
+ break
46
+ else :
47
+ propositions [elve ] = [elve ] # Looks like it had nowhere to move!
48
+
49
+ checks = checks [1 :] + [checks [0 ]]
50
+
51
+ # print(propositions)
52
+
53
+ data = []
54
+ for proposed , candiates in propositions .items ():
55
+ if len (candiates ) == 1 :
56
+ data .append (proposed )
57
+ else :
58
+ data .extend (candiates ) # Too many elves wishing move to proposed point!
59
+
60
+ # plotElves(data)
61
+ # if len(data) != 22:
62
+ # print("WTF!!")
63
+ # print(propositions)
64
+
65
+ # print(len(data))
66
+
67
+ return (max (x for x , y in data ) - min (x for x , y in data ) + 1 ) * (max (y for x , y in data ) - min (y for x , y in data ) + 1 ) - len (data )
68
+
69
+ def plotElves (elves ):
70
+ minX = min (x for x , y in elves )
71
+ maxX = max (x for x , y in elves ) + 1
72
+ minY = min (y for x , y in elves )
73
+ maxY = max (y for x , y in elves ) + 1
74
+
75
+ for y in range (minY , maxY ):
76
+ for x in range (minX , maxX ):
77
+ print ("#" if (x , y ) in elves else "." , end = '' )
78
+ print ()
79
+
80
+ def part2 (data ):
81
+ # Took 14.1 minutes but it works
82
+ def empty (check , point ):
83
+ return all ((point [0 ]+ dx , point [1 ]+ dy ) not in data for dx , dy in check )
84
+
85
+
86
+ north = [(- 1 , - 1 ), ( 0 , - 1 ), ( 1 , - 1 )] # NW, N, NE
87
+ south = [(- 1 , 1 ), ( 0 , 1 ), ( 1 , 1 )] # SW, S, SE
88
+ west = [(- 1 , - 1 ), (- 1 , 0 ), (- 1 , 1 )] # NW, W, SW
89
+ east = [( 1 , - 1 ), ( 1 , 0 ), ( 1 , 1 )] # NE, E, SE
90
+ allD = [(dx , dy ) for dy in range (- 1 , 2 ) for dx in range (- 1 , 2 ) if (dx , dy ) != (0 , 0 )]
91
+
92
+ checks = [north , south , west , east ]
93
+
94
+ i = 0
95
+ while True :
96
+ i += 1
97
+ print ('Simulation Step:' , i )
98
+ moved = False
99
+ propositions = {}
100
+
101
+ for elve in data :
102
+ if empty (allD , elve ): # No move
103
+ propositions [elve ] = [elve ]
104
+ continue
105
+
106
+ moved = True
107
+ for check in checks :
108
+ if empty (check , elve ):
109
+ # print(f'Found a valid check for {elve} elve: {check[1]}')
110
+ px , py = elve [0 ]+ check [1 ][0 ], elve [1 ]+ check [1 ][1 ]
111
+ propositions [(px , py )] = propositions .get ((px , py ), []) + [elve ]
112
+ break
113
+ else :
114
+ propositions [elve ] = [elve ] # Looks like it had nowhere to move!
115
+
116
+ checks = checks [1 :] + [checks [0 ]]
117
+
118
+ if not moved :
119
+ break
120
+
121
+ # print(propositions)
122
+
123
+ data = []
124
+ for proposed , candiates in propositions .items ():
125
+ if len (candiates ) == 1 :
126
+ data .append (proposed )
127
+ else :
128
+ data .extend (candiates ) # Too many elves wishing move to proposed point!
129
+
130
+ # plotElves(data)
131
+ # if len(data) != 22:
132
+ # print("WTF!!")
133
+ # print(propositions)
134
+
135
+ # print(len(data))
136
+
137
+ return i
0 commit comments