1
+ from functools import total_ordering
2
+ import re
3
+
4
+ @total_ordering
5
+ class Valve :
6
+ def __init__ (self , name , flow , to_names ):
7
+ self .name = name
8
+ self .flow = flow
9
+ self .to_names = to_names
10
+ self .to = []
11
+ self .open = False
12
+ self .flowed = 0
13
+
14
+ def __eq__ (self , other ):
15
+ return self .name .__eq__ (other .name )
16
+
17
+ def __lt__ (self , other ):
18
+ return self .flow .__lt__ (other .flow )
19
+
20
+ def __le__ (self , other ):
21
+ return self .flow .__le__ (other .flow )
22
+
23
+ def __gt__ (self , other ):
24
+ return self .flow .__gt__ (other .flow )
25
+
26
+ def __ge__ (self , other ):
27
+ return self .flow .__ge__ (other .flow )
28
+
29
+ def tick (self ):
30
+ if self .open :
31
+ self .flowed += self .flow
32
+
33
+ class Cave :
34
+ def __init__ (self , filename ) -> None :
35
+ with open (filename ) as file :
36
+ self .data = file .read ()
37
+ pattern = re .compile (r'^Valve ([A-Z]{2}) has flow rate=(\d+); tunnels lead to valves ((?:[A-Z][A-Z][, ]*)+)' )
38
+ self .valves = []
39
+ for line in self .data .splitlines ():
40
+ if match := pattern .match (line ):
41
+ valve = Valve (
42
+ name = match .group (1 ),
43
+ flow = int (match .group (2 )),
44
+ to_names = match .group (3 ).split (', ' ),
45
+ )
46
+ self .valves .append (valve )
47
+ for valve in self .valves :
48
+ valve .to = list ([to_valve for to_valve in self .valves if to_valve .name in valve .to_names ])
49
+ self .current = self .valves [0 ]
50
+
51
+ def do (self , minutes = 30 ):
52
+ for _ in range (minutes ):
53
+ for valve in self .valves :
54
+ valve .tick ()
55
+ # One deep search
56
+ if most_promising := max (valve for valve in self .current .to if not valve .open ):
57
+ if most_promising .flow > self .current .flow + 1 or self .current .open :
58
+ print (f'You move to valve { most_promising .name } .' )
59
+ self .current = most_promising
60
+ continue
61
+ print (f'You open valve { self .current .name } .' )
62
+ self .current .open = True
63
+ return sum ([valve .flowed for valve in self .valves ])
0 commit comments