8
8
import java .util .stream .IntStream ;
9
9
10
10
import static com .sbaars .adventofcode .common .ReadsFormattedString .readString ;
11
+ import static com .sbaars .adventofcode .util .AOCUtils .allPairs ;
11
12
12
13
public class Day16 extends Day2022 {
13
14
@@ -27,6 +28,7 @@ public static void main(String[] args) {
27
28
28
29
public record Valve (String name , long flow , String others ) {}
29
30
public record State (Map <String , Long > open , int index , long totalFlow ) {}
31
+ public record State2 (Map <String , Long > open , int myIndex , int elephantIndex , long totalFlow ) {}
30
32
31
33
@ Override
32
34
public Object part1 () {
@@ -59,6 +61,51 @@ public Object part1() {
59
61
60
62
@ Override
61
63
public Object part2 () {
62
- return "" ;
64
+ List <Valve > in = dayStream ().map (s -> {
65
+ try {
66
+ return readString (s , "Valve %s has flow rate=%n; tunnels lead to valves %s" , Valve .class );
67
+ } catch (IllegalStateException e ) {
68
+ return readString (s , "Valve %s has flow rate=%n; tunnel leads to valve %s" , Valve .class );
69
+ }
70
+ }).toList ();
71
+ Set <String > openable = in .stream ().filter (s -> s .flow > 0 ).map (Valve ::name ).collect (Collectors .toSet ());
72
+ Map <String , Integer > indices = IntStream .range (0 , in .size ()).boxed ().collect (Collectors .toMap (i -> in .get (i ).name , i -> i ));
73
+ Set <State2 > states = new HashSet <>();
74
+ states .add (new State2 (new HashMap <>(), 0 , 0 , 0 ));
75
+ for (int minutes = 0 ; minutes <30 ; minutes ++) {
76
+ Set <State2 > newStates = new HashSet <>();
77
+ for (State2 s : states ) {
78
+
79
+ Valve myValve = in .get (s .myIndex );
80
+ Valve eleValve = in .get (s .elephantIndex );
81
+ long flow = s .open .values ().stream ().mapToLong (e -> e ).sum () + s .totalFlow ;
82
+ if (s .open .keySet ().equals (openable )) { // All valves are open, time to chill
83
+ newStates .add (new State2 (s .open , s .myIndex , s .elephantIndex , flow ));
84
+ }
85
+ boolean couldOpen = false ;
86
+ if (myValve .flow > 0 && !s .open .containsKey (myValve .name )) {
87
+ Map <String , Long > newOpen = new HashMap <>(s .open );
88
+ newOpen .put (myValve .name , myValve .flow );
89
+ Arrays .stream (eleValve .others .split (", " )).forEach (name -> newStates .add (new State2 (newOpen , s .myIndex , indices .get (name ), flow )));
90
+ couldOpen = true ;
91
+ }
92
+ if (eleValve .flow > 0 && !s .open .containsKey (eleValve .name )) {
93
+ Map <String , Long > newOpen = new HashMap <>(s .open );
94
+ newOpen .put (eleValve .name , eleValve .flow );
95
+ Arrays .stream (myValve .others .split (", " )).forEach (name -> newStates .add (new State2 (newOpen , indices .get (name ), s .elephantIndex , flow )));
96
+ couldOpen = true ;
97
+ }
98
+ if (myValve .flow > 0 && !s .open .containsKey (myValve .name ) && eleValve .flow > 0 && !s .open .containsKey (eleValve .name )) {
99
+ Map <String , Long > newOpen = new HashMap <>(s .open );
100
+ newOpen .put (myValve .name , myValve .flow );
101
+ newOpen .put (eleValve .name , eleValve .flow );
102
+ newStates .add (new State2 (newOpen , s .myIndex , s .elephantIndex , flow ));
103
+ couldOpen = true ;
104
+ }
105
+ if (!couldOpen ) allPairs (List .of (myValve .others .split (", " )), List .of (eleValve .others .split (", " ))).forEach (p -> newStates .add (new State2 (s .open , indices .get (p .a ()), indices .get (p .b ()), flow )));
106
+ }
107
+ states = newStates ;
108
+ }
109
+ return states .stream ().mapToLong (State2 ::totalFlow ).max ().getAsLong ();
63
110
}
64
111
}
0 commit comments