1- use std:: collections :: { HashMap , HashSet } ;
2- use std:: hash :: Hash ;
3- use std:: iter:: successors;
1+ use std:: cmp :: { max , min } ;
2+ use std:: collections :: { HashSet , VecDeque } ;
3+ use std:: iter:: { once , successors} ;
44
55use aoclp:: positioning:: pt:: { rectangular_area, Pt } ;
66use aoclp:: solvers_impl:: input:: safe_get_input_as_many;
77use itertools:: Itertools ;
8- use strum :: EnumIs ;
8+ use aoclp :: num :: Zero ;
99
1010pub fn part_1 ( ) -> i64 {
1111 input ( )
@@ -16,37 +16,56 @@ pub fn part_1() -> i64 {
1616 . unwrap ( )
1717}
1818
19- pub fn part_2 ( ) -> usize {
20- 0
21- }
19+ pub fn part_2 ( ) -> i64 {
20+ let red_tiles = input ( ) ;
2221
23- #[ derive( Debug , Default , Copy , Clone , PartialEq , Eq , Hash , EnumIs ) ]
24- enum Tile {
25- #[ default]
26- Pink ,
27- Red ,
28- Green ,
29- }
22+ let path: HashSet < _ > = red_tiles
23+ . iter ( )
24+ . copied ( )
25+ . chain ( once ( red_tiles[ 0 ] ) )
26+ . enumerate ( )
27+ . tuple_windows ( )
28+ . flat_map ( |( ( ia, a) , ( ib, b) ) | {
29+ let displacement = Pt :: new ( ( b. x - a. x ) . signum ( ) , ( b. y - a. y ) . signum ( ) ) ;
30+ if displacement. x != 0 && displacement. y != 0 {
31+ panic ! ( "Pair {} (#{ia}), {} (#{ib}) have wrong displacement" , a. to_string( ) , b. to_string( ) )
32+ }
33+ successors ( Some ( a) , move |& p| ( p != b) . then_some ( p + displacement) )
34+ . chain ( once ( b) )
35+ } )
36+ . collect ( ) ;
3037
31- # [ derive ( Debug , Clone ) ]
32- struct Floor ( HashMap < Pt , Tile > ) ;
38+ let floor_width = red_tiles . iter ( ) . map ( |p| p . x ) . max ( ) . unwrap ( ) + 2 ;
39+ let floor_height = red_tiles . iter ( ) . map ( |p| p . y ) . max ( ) . unwrap ( ) + 2 ;
3340
34- impl Default for Floor {
35- fn default ( ) -> Self {
36- let tiles = input ( ) ;
41+ let mut lava = HashSet :: new ( ) ;
42+ let mut q = VecDeque :: new ( ) ;
43+ q. push_back ( Pt :: zero ( ) ) ;
44+ while let Some ( p) = q. pop_front ( ) {
45+ if !p. within ( 0 ..floor_width, 0 ..floor_height) || path. contains ( & p) {
46+ continue ;
47+ }
48+ if lava. insert ( p) {
49+ q. extend ( p. four_neighbours ( ) ) ;
50+ }
51+ }
3752
38- let _path: HashSet < _ > = tiles
39- . iter ( )
40- . tuple_windows ( )
41- . flat_map ( |( a, b) | {
42- let displacement = Pt :: new ( ( b. x - a. x ) . signum ( ) , ( b. y - a. y ) . signum ( ) ) ;
43- let b = * b;
44- successors ( Some ( * a) , move |& p| ( p != b) . then_some ( p + displacement) )
53+ let safe_rectangle = |a : Pt , b : Pt | -> bool {
54+ ( min ( a. y , b. y ) ..=max ( a. y , b. y ) )
55+ . into_iter ( )
56+ . flat_map ( |y| {
57+ ( min ( a. x , b. x ) ..=max ( a. x , b. x ) ) . into_iter ( ) . map ( move |x| Pt :: new ( x, y) )
4558 } )
46- . collect ( ) ;
59+ . all ( |p| !lava. contains ( & p) )
60+ } ;
4761
48- todo ! ( )
49- }
62+ red_tiles
63+ . into_iter ( )
64+ . array_combinations ( )
65+ . filter ( |& [ a, b] | safe_rectangle ( a, b) )
66+ . map ( |[ a, b] | rectangular_area ( a, b) )
67+ . max ( )
68+ . unwrap ( )
5069}
5170
5271fn input ( ) -> Vec < Pt > {
0 commit comments