@@ -3,6 +3,41 @@ use crate::util::parse::*;
33
44type Tile = [ u64 ; 2 ] ;
55
6+ struct Candidate {
7+ x : u64 ,
8+ y : u64 ,
9+ interval : Interval ,
10+ }
11+
12+ /// The set { x in u64 | l <= x <= r }.
13+ #[ derive( Clone , Copy ) ]
14+ struct Interval {
15+ l : u64 ,
16+ r : u64 ,
17+ }
18+
19+ impl Interval {
20+ fn new ( l : u64 , r : u64 ) -> Self {
21+ debug_assert ! ( l <= r) ;
22+
23+ Interval { l, r }
24+ }
25+
26+ fn intersects ( self , other : Self ) -> bool {
27+ other. l <= self . r && self . l <= other. r
28+ }
29+
30+ fn intersection ( self , other : Self ) -> Self {
31+ debug_assert ! ( self . intersects( other) ) ;
32+
33+ Interval :: new ( self . l . max ( other. l ) , self . r . min ( other. r ) )
34+ }
35+
36+ fn contains ( self , x : u64 ) -> bool {
37+ self . l <= x && x <= self . r
38+ }
39+ }
40+
641pub fn parse ( input : & str ) -> Vec < Tile > {
742 input. iter_unsigned :: < u64 > ( ) . chunk :: < 2 > ( ) . collect ( )
843}
@@ -33,12 +68,6 @@ pub fn part2(tiles: &[Tile]) -> u64 {
3368
3469 // Each red tile (`x`, `y`) becomes a candidate for being a top corner of the largest area, and during the
3570 // scan the `interval` containing the maximum possible width is updated:
36- struct Candidate {
37- x : u64 ,
38- y : u64 ,
39- interval : Interval ,
40- }
41-
4271 let mut candidates: Vec < Candidate > = Vec :: with_capacity ( 512 ) ;
4372
4473 // Maintain an ordered list of descending edges, i.e. [begin_interval_0, end_interval_0, begin_interval_1, end_interval_1, ...]:
@@ -74,7 +103,7 @@ pub fn part2(tiles: &[Tile]) -> u64 {
74103 ) ;
75104
76105 // Check the rectangles this red tile could be a bottom tile for, with the current candidates:
77- for candidate in candidates. iter ( ) {
106+ for candidate in & candidates {
78107 for x in [ x0, x1] {
79108 if candidate. interval . contains ( x) {
80109 largest_area = largest_area
@@ -109,35 +138,6 @@ pub fn part2(tiles: &[Tile]) -> u64 {
109138 largest_area
110139}
111140
112- /// The set { x in u64 | l <= x <= r }.
113- #[ derive( Clone , Copy ) ]
114- struct Interval {
115- l : u64 ,
116- r : u64 ,
117- }
118-
119- impl Interval {
120- fn new ( l : u64 , r : u64 ) -> Self {
121- debug_assert ! ( l <= r) ;
122-
123- Interval { l, r }
124- }
125-
126- fn intersects ( self , other : Self ) -> bool {
127- other. l <= self . r && self . l <= other. r
128- }
129-
130- fn intersection ( self , other : Self ) -> Self {
131- debug_assert ! ( self . intersects( other) ) ;
132-
133- Interval :: new ( self . l . max ( other. l ) , self . r . min ( other. r ) )
134- }
135-
136- fn contains ( self , x : u64 ) -> bool {
137- self . l <= x && x <= self . r
138- }
139- }
140-
141141// Adds `value` if it isn't in `ordered_list`, removes it if it is, maintaining the order.
142142fn toggle_value_membership_in_ordered_list ( ordered_list : & mut Vec < u64 > , value : u64 ) {
143143 let mut i = 0 ;
0 commit comments