1- use aoc_lib:: matrix:: Grid ;
1+ use aoc_lib:: { direction :: ordinal , matrix:: Grid } ;
22use common:: { Answer , solution} ;
3- use nd_vec:: Vec2 ;
43
54solution ! ( "Printing Department" , 4 ) ;
65
7- #[ derive( Clone ) ]
6+ #[ derive( Clone , PartialEq , Eq ) ]
87enum Tile {
98 Empty ,
109 Roll ,
1110}
1211
1312fn part_a ( input : & str ) -> Answer {
14- let grid = Grid :: parse ( input, |chr| match chr {
15- '.' => Tile :: Empty ,
16- '@' => Tile :: Roll ,
17- _ => panic ! ( ) ,
18- } ) ;
19-
20- count ( & grid) . 0 . into ( )
13+ let ( count, _) = count ( & parse ( input) ) ;
14+ count. into ( )
2115}
2216
2317fn part_b ( input : & str ) -> Answer {
24- let mut grid = Grid :: parse ( input, |chr| match chr {
25- '.' => Tile :: Empty ,
26- '@' => Tile :: Roll ,
27- _ => panic ! ( ) ,
28- } ) ;
29-
18+ let mut grid = parse ( input) ;
3019 let mut out = 0 ;
3120
3221 loop {
@@ -41,47 +30,32 @@ fn part_b(input: &str) -> Answer {
4130 out. into ( )
4231}
4332
44- fn count ( grid : & Grid < Tile > ) -> ( u32 , Grid < Tile > ) {
45- let mut out = 0 ;
33+ fn parse ( input : & str ) -> Grid < Tile > {
34+ Grid :: parse ( input, |chr| match chr {
35+ '.' => Tile :: Empty ,
36+ '@' => Tile :: Roll ,
37+ _ => panic ! ( ) ,
38+ } )
39+ }
4640
41+ fn count ( grid : & Grid < Tile > ) -> ( u32 , Grid < Tile > ) {
4742 let mut next = grid. clone ( ) ;
43+ let mut count = 0 ;
4844
49- for y in 0 ..grid. size . y ( ) {
50- for x in 0 ..grid. size ( ) . x ( ) {
51- let pos = Vec2 :: new ( [ x, y] ) . num_cast :: < i32 > ( ) . unwrap ( ) ;
52- if matches ! ( grid. get( pos. num_cast( ) . unwrap( ) ) . unwrap( ) , Tile :: Empty ) {
53- continue ;
54- }
55-
56- let mut neighbors = 0 ;
57- for dy in -1 ..=1 {
58- for dx in -1 ..=1 {
59- let delta = Vec2 :: new ( [ dx, dy] ) ;
60- let check = pos + delta;
61-
62- if delta == Vec2 :: zero ( )
63- || check. x ( ) < 0
64- || check. y ( ) < 0
65- || check. x ( ) >= grid. size . x ( ) as i32
66- || check. y ( ) >= grid. size . y ( ) as i32
67- {
68- continue ;
69- }
70-
71- if matches ! ( grid. get( check. num_cast( ) . unwrap( ) ) . unwrap( ) , Tile :: Roll ) {
72- neighbors += 1 ;
73- }
74- }
75- }
45+ for ( pos, _tile) in grid. iter ( ) . filter ( |x| * x. 1 == Tile :: Roll ) {
46+ let mut neighbors = 0 ;
47+ for dir in ordinal:: Direction :: ALL {
48+ let tile = dir. try_advance ( pos) . and_then ( |pos| grid. get ( pos) ) ;
49+ neighbors += ( tile == Some ( & Tile :: Roll ) ) as u32 ;
50+ }
7651
77- if neighbors < 4 {
78- out += 1 ;
79- next. set ( pos, Tile :: Empty ) ;
80- }
52+ if neighbors < 4 {
53+ count += 1 ;
54+ next. set ( pos, Tile :: Empty ) ;
8155 }
8256 }
8357
84- ( out , next)
58+ ( count , next)
8559}
8660
8761#[ cfg( test) ]
0 commit comments