@@ -7,75 +7,56 @@ use common::{Answer, solution};
77use itertools:: Itertools ;
88use nd_vec:: { Vec3 , vector} ;
99
10+ type Pos = Vec3 < i64 > ;
11+ type Pair = ( Pos , Pos ) ;
12+
1013solution ! ( "Playground" , 8 ) ;
1114
1215fn part_a ( input : & str ) -> Answer {
13- let boxes = input
14- . lines ( )
15- . map ( |x| {
16- let mut coords = x. split ( ',' ) . map ( |x| x. parse :: < i64 > ( ) . unwrap ( ) ) ;
17- vector ! (
18- coords. next( ) . unwrap( ) ,
19- coords. next( ) . unwrap( ) ,
20- coords. next( ) . unwrap( )
21- )
22- } )
23- . collect :: < Vec < _ > > ( ) ;
24-
25- let mut closest_paris = boxes
26- . iter ( )
27- . combinations ( 2 )
28- . map ( |x| ( ( * x[ 0 ] - * x[ 1 ] ) . magnitude_squared ( ) , ( * x[ 0 ] , * x[ 1 ] ) ) )
29- . collect :: < Vec < _ > > ( ) ;
30- closest_paris. sort_by_key ( |x| x. 0 ) ;
31-
32- let mut connections = HashMap :: new ( ) ;
33- for ( _dist, ( a, b) ) in closest_paris. iter ( ) . take ( 1000 ) {
34- println ! ( "connecting {a:?} and {b:?}" ) ;
35-
36- connections. entry ( * a) . or_insert ( HashSet :: new ( ) ) . insert ( * b) ;
37- connections. entry ( * b) . or_insert ( HashSet :: new ( ) ) . insert ( * a) ;
38- }
39-
40- // get the length of every unique sub graph
41- fn subgraph_size (
42- connections : & HashMap < Vec3 < i64 > , HashSet < Vec3 < i64 > > > ,
43- seen : & mut HashSet < Vec3 < i64 > > ,
44- node : Vec3 < i64 > ,
45- ) -> u64 {
46- if !seen. insert ( node) {
47- return 0 ;
48- }
49-
50- let children = & connections[ & node] ;
16+ let ( boxes, closest_paris) = parse ( input) ;
5117
52- let mut out = 1 ;
53- for child in children {
54- out += subgraph_size ( connections, seen, * child) ;
55- }
56-
57- out
18+ let mut connections = HashMap :: < _ , Vec < _ > > :: new ( ) ;
19+ let n = [ 1000 , 10 ] [ cfg ! ( test) as usize ] ;
20+ for ( _dist, ( a, b) ) in closest_paris. iter ( ) . take ( n) {
21+ connections. entry ( * a) . or_default ( ) . push ( * b) ;
22+ connections. entry ( * b) . or_default ( ) . push ( * a) ;
5823 }
5924
6025 let mut seen = HashSet :: new ( ) ;
6126 let mut sizes = Vec :: new ( ) ;
6227 for start in connections. keys ( ) {
6328 let size = subgraph_size ( & connections, & mut seen, * start) ;
64- if size > 0 {
65- sizes. push ( size) ;
66- println ! ( "{start:?} is in a {size} node circuit" ) ;
67- }
29+ ( size > 0 ) . then ( || sizes. push ( size) ) ;
6830 }
6931
7032 let unconnected = boxes. iter ( ) . filter ( |x| !seen. contains ( x) ) . count ( ) ;
7133 sizes. extend ( repeat_n ( 1 , unconnected) ) ;
72-
7334 sizes. sort ( ) ;
7435
7536 sizes. iter ( ) . rev ( ) . take ( 3 ) . product :: < u64 > ( ) . into ( )
7637}
7738
7839fn part_b ( input : & str ) -> Answer {
40+ let ( boxes, closest_paris) = parse ( input) ;
41+
42+ let mut connections = HashMap :: < _ , Vec < _ > > :: new ( ) ;
43+ for ( _dist, ( a, b) ) in closest_paris. iter ( ) {
44+ connections. entry ( * a) . or_default ( ) . push ( * b) ;
45+ connections. entry ( * b) . or_default ( ) . push ( * a) ;
46+
47+ let mut seen = HashSet :: new ( ) ;
48+ for start in connections. keys ( ) {
49+ let size = subgraph_size ( & connections, & mut seen, * start) ;
50+ if size == boxes. len ( ) as u64 {
51+ return ( a. x ( ) * b. x ( ) ) . into ( ) ;
52+ }
53+ }
54+ }
55+
56+ ( ) . into ( )
57+ }
58+
59+ fn parse ( input : & str ) -> ( Vec < Pos > , Vec < ( i64 , Pair ) > ) {
7960 let boxes = input
8061 . lines ( )
8162 . map ( |x| {
@@ -95,46 +76,24 @@ fn part_b(input: &str) -> Answer {
9576 . collect :: < Vec < _ > > ( ) ;
9677 closest_paris. sort_by_key ( |x| x. 0 ) ;
9778
98- let mut connections = HashMap :: new ( ) ;
99- for ( _dist, ( a, b) ) in closest_paris. iter ( ) {
100- connections. entry ( * a) . or_insert ( HashSet :: new ( ) ) . insert ( * b) ;
101- connections. entry ( * b) . or_insert ( HashSet :: new ( ) ) . insert ( * a) ;
102-
103- //
104-
105- let mut seen = HashSet :: new ( ) ;
106- for start in connections. keys ( ) {
107- subgraph_size ( & connections, & mut seen, * start) ;
108- }
109-
110- let unconnected = boxes. iter ( ) . filter ( |x| !seen. contains ( x) ) . count ( ) ;
79+ ( boxes, closest_paris)
80+ }
11181
112- if unconnected == 0 {
113- return ( a. x ( ) * b. x ( ) ) . into ( ) ;
114- }
82+ fn subgraph_size (
83+ connections : & HashMap < Vec3 < i64 > , Vec < Vec3 < i64 > > > ,
84+ seen : & mut HashSet < Vec3 < i64 > > ,
85+ node : Vec3 < i64 > ,
86+ ) -> u64 {
87+ if !seen. insert ( node) {
88+ return 0 ;
11589 }
11690
117- // get the length of every unique sub graph
118- fn subgraph_size (
119- connections : & HashMap < Vec3 < i64 > , HashSet < Vec3 < i64 > > > ,
120- seen : & mut HashSet < Vec3 < i64 > > ,
121- node : Vec3 < i64 > ,
122- ) -> u64 {
123- if !seen. insert ( node) {
124- return 0 ;
125- }
126-
127- let children = & connections[ & node] ;
128-
129- let mut out = 1 ;
130- for child in children {
131- out += subgraph_size ( connections, seen, * child) ;
132- }
133-
134- out
91+ let mut out = 1 ;
92+ for child in & connections[ & node] {
93+ out += subgraph_size ( connections, seen, * child) ;
13594 }
13695
137- ( ) . into ( )
96+ out
13897}
13998
14099#[ cfg( test) ]
0 commit comments