77// <https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12>.
88// See the Licence for the specific language governing permissions and limitations under the Licence.
99
10- use std:: { collections :: HashMap , fmt:: Display } ;
10+ use std:: fmt:: Display ;
1111
1212use itertools:: Itertools ;
13- use num:: Integer ;
1413
15- use crate :: { AoCError , BigCoord2D , CommonGrid , Coordinate , Coordinate2D , symbols} ;
14+ use crate :: { AoCError , BigCoord2D , CommonGrid , Coordinate , symbols} ;
1615
1716pub fn part_1 ( data : crate :: DataIn ) -> crate :: AoCResult < String > {
1817 let coords: Vec < BigCoord2D > = data. map ( |line| line. parse ( ) ) . try_collect ( ) ?;
@@ -36,58 +35,6 @@ pub fn part_1(data: crate::DataIn) -> crate::AoCResult<String> {
3635 Ok ( ret. to_string ( ) )
3736}
3837
39- /// Adapted from http://web.archive.org/web/20080812141848/http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/
40- fn inside_polygon ( point : BigCoord2D , polygon : & [ BigCoord2D ] ) -> bool {
41- polygon
42- . iter ( )
43- . tuple_windows ( )
44- . filter ( |( poly_a, poly_b) | {
45- let poly_min = poly_a. get_min ( poly_b) ;
46- let poly_max = poly_a. get_max ( poly_b) ;
47- if point. y <= poly_min. y {
48- // why does this only check y coords? who knows.
49- return false ;
50- } else if point. x > poly_max. x || point. y > poly_max. y {
51- return false ;
52- } else if poly_a. y == poly_b. y {
53- // ????
54- return false ;
55- }
56- // mystery statement
57- let xinters =
58- ( point. y - poly_a. y ) * ( poly_b. x - poly_a. x ) / ( poly_b. y - poly_a. y ) + poly_a. x ;
59- poly_a. x == poly_b. x || point. x <= xinters
60- } )
61- . count ( )
62- . is_odd ( )
63- }
64-
65- fn cached_inside_polygon (
66- point : BigCoord2D ,
67- polygon : & [ BigCoord2D ] ,
68- prechecked : & mut HashMap < BigCoord2D , bool > ,
69- ) -> bool {
70- if let Some ( result) = prechecked. get ( & point) {
71- return * result;
72- }
73- let result = inside_polygon ( point, polygon) ;
74- log:: trace!(
75- "Magic function says {point} is {} poly" ,
76- if result { "inside" } else { "outside" }
77- ) ;
78- prechecked. insert ( point, result) ;
79- result
80- }
81-
82- fn rectangulate ( a : & BigCoord2D , b : & BigCoord2D ) -> impl Iterator < Item = BigCoord2D > {
83- log:: trace!( "wtf wtf {a} {b}" ) ;
84- // I'm moderately sure I've written this code before but I don't know where it is
85- ( a. x ..=b. x )
86- . cartesian_product ( a. y ..=b. y )
87- . map ( BigCoord2D :: from_tuple)
88- . inspect ( |c| log:: trace!( "wtf {c}" ) )
89- }
90-
9138pub fn part_2 ( data : crate :: DataIn ) -> crate :: AoCResult < String > {
9239 let coords = {
9340 let mut coords: Vec < BigCoord2D > = data. map ( |line| line. parse ( ) ) . try_collect ( ) ?;
@@ -96,7 +43,7 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
9643 coords
9744 } ;
9845
99- let mut prechecked : HashMap < BigCoord2D , bool > = coords
46+ let lines : Vec < BigCoord2D > = coords
10047 . iter ( )
10148 . tuple_windows ( )
10249 . flat_map ( |( a, b) | {
@@ -110,7 +57,6 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
11057 ( a. y ..=b. y ) . map ( |y| BigCoord2D { x, y } ) . collect_vec ( )
11158 }
11259 } )
113- . map ( |c| ( c, true ) )
11460 . collect ( ) ;
11561
11662 // stupid test grid
@@ -139,7 +85,7 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
13985 }
14086
14187 let mut grid: SparseGrid <GridState , BigCoord2D > =
142- prechecked . keys ( ) . map( |a| ( * a, GridState :: Green ) ) . collect( ) ;
88+ lines . iter ( ) . map( |a| ( * a, GridState :: Green ) ) . collect( ) ;
14389
14490 coords. iter( ) . for_each( |c| {
14591 grid. set( * c, GridState :: Red ) ;
@@ -161,60 +107,19 @@ pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
161107 . inspect ( |( dist, a, b) | {
162108 log:: debug!( "Square of area {dist} between {a} and {b}" ) ;
163109 } )
164- . find ( |( _, a, b) | {
165- rectangulate ( a, b) . all ( |point| cached_inside_polygon ( point, & coords, & mut prechecked) )
110+ . filter ( |( _, min, max) | {
111+ !coords
112+ . iter ( )
113+ . any ( |c| c. x > min. x && c. y > min. y && c. x < max. x && c. y < max. y )
114+ } )
115+ . find ( |( _, min, max) | {
116+ !lines
117+ . iter ( )
118+ . any ( |c| c. x > min. x && c. y > min. y && c. x < max. x && c. y < max. y )
166119 } )
167120 . map ( |( dist, _, _) | dist)
168121 . ok_or ( AoCError :: new ( "No valid rectangles?" ) ) ?;
169122
170- // stupid test grid v2
171- log:: debug!( "postchecked:\n {}" , {
172- use aoc_macros:: VoidState ;
173-
174- use crate :: SparseGrid ;
175-
176- #[ derive( Debug , VoidState ) ]
177- enum GridState {
178- #[ void]
179- Void ,
180- Red ,
181- Green ,
182- White ,
183- }
184-
185- impl Display for GridState {
186- fn fmt( & self , f: & mut std:: fmt:: Formatter <' _>) -> std:: fmt:: Result {
187- match self {
188- Self :: Void => symbols:: VOID ,
189- Self :: Red => symbols:: BLOCK ,
190- Self :: Green => symbols:: SHADE_DARK ,
191- Self :: White => symbols:: SHADE_LIGHT ,
192- }
193- . fmt( f)
194- }
195- }
196-
197- let mut grid: SparseGrid <GridState , BigCoord2D > = prechecked
198- . iter( )
199- . map( |( coord, state) | {
200- (
201- * coord,
202- if * state {
203- GridState :: Green
204- } else {
205- GridState :: White
206- } ,
207- )
208- } )
209- . collect( ) ;
210-
211- coords. iter( ) . for_each( |c| {
212- grid. set( * c, GridState :: Red ) ;
213- } ) ;
214-
215- grid
216- } ) ;
217-
218123 Ok ( ret. to_string ( ) )
219124}
220125
0 commit comments