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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#!/usr/bin/env python3
# import numpy as np
from functools import reduce
from re import findall
from copy import deepcopy
from collections import defaultdict
import sys
# filename = "in/day23.ref"
# filename = 'in/day23_2.ref'
filename = "in/day23.pzl"
data = open(filename).read()
lines = [line for line in data.rstrip('\n').split('\n')]
# print(lines)
E = set()
for y,line in enumerate(lines):
for x,val in enumerate(line):
if val == '#':
E.add((y,x))
# print(E)
def check_N(E, y, x):
if all( [(y+dy, x+dx) not in E for dy,dx in [[-1,0], [-1,1], [-1,-1]]] ):
return y-1, x
else:
return None
def check_S(E, y, x):
if all( [(y+dy, x+dx) not in E for dy,dx in [[1,0], [1,1], [1,-1]]] ):
return y+1, x
else:
return None
def check_W(E, y, x):
if all( [(y+dy, x+dx) not in E for dy,dx in [[0,-1], [1,-1], [-1,-1]]] ):
return y, x-1
else:
return None
def check_E(E, y, x):
if all( [(y+dy, x+dx) not in E for dy,dx in [[0,1], [1,1], [-1,1]]] ):
return y, x+1
else:
return None
C = [check_N, check_S, check_W, check_E]
def get_max(E):
min_y = 1000
max_y = 0
min_x = 1000
max_x = 0
for y,x in E:
min_y = min(min_y, y)
max_y = max(max_y, y)
min_x = min(min_x, x)
max_x = max(max_x, x)
return min_y, max_y, min_x, max_x
def print_elfs(E):
min_y, max_y, min_x, max_x = get_max(E)
for y in range(min_y - 5, max_y + 5):
for x in range(min_x - 5, max_x + 5):
if y == 0 and x == 0:
print('o', end='')
elif (y,x) in E:
print('#', end='')
else:
print('.', end='')
print()
print()
print()
def get_new_pos(E, y, x, checks):
checks = checks[:]
move = False
for dy,dx in [0,1], [0,-1], [1,0], [-1,0], [1,1], [1,-1], [-1,-1], [-1,1]:
if (y+dy, x+dx) in E:
move = True
break
if move == False:
return y, x
for i,check in enumerate(checks):
ret = check(E,y,x)
if ret != None:
y, x = ret
break
return y,x
# print_elfs(E)
for round_n in range(1,10000+1):
# print(round_n)
Ec = E.copy()
dest = defaultdict(list)
for y,x in E:
ny,nx = get_new_pos(E,y,x,C)
dest[(ny,nx)].append((y,x))
C.append(C.pop(0))
for ey,ex in dest:
if len(dest[(ey,ex)]) > 1:
continue
sy,sx = dest[(ey,ex)][0]
# print(sy,sx, ey,ex)
E.remove((sy,sx))
E.add((ey,ex))
# print_elfs(E)
if round_n == 10:
res1 = 0
min_y, max_y, min_x, max_x = get_max(E)
for y in range(min_y, max_y+1):
for x in range(min_x, max_x+1):
if (y,x) not in E:
res1 += 1
if E == Ec:
res2 = round_n
break
print('res1:', res1)
print('res2:', res2)
|