2020-12-17 14:04:05 +01:00
#![ feature(test) ]
extern crate test ;
2020-12-17 14:51:05 +01:00
use aoc2020 ::{
common ::* , grid ::{ cell ::Cell , * }
} ;
2020-12-17 14:04:05 +01:00
type Parsed = Grid < Position3D , Cell > ;
fn read_input ( ) -> String {
read_file ( 17 )
}
fn parse_input ( raw : & str ) -> Parsed {
2020-12-17 14:13:02 +01:00
raw . lines ( )
. enumerate ( )
. flat_map ( move | ( y , l ) | l . bytes ( ) . enumerate ( ) . map ( move | ( x , b ) | ( ( x , y , 0 ) . into ( ) , b . into ( ) ) ) )
. collect ( )
2020-12-17 14:04:05 +01:00
}
fn count_live_neighbors ( p : & Position3D , grid : & Parsed ) -> usize {
p . neighbors ( ) . iter ( ) . filter ( | & n | grid . get ( * n ) = = Cell ::Alive ) . count ( )
}
2020-12-17 14:13:02 +01:00
fn make_step ( input : Parsed ) -> Parsed {
2020-12-17 14:04:05 +01:00
let readonly = input . clone ( ) ;
2020-12-17 14:13:02 +01:00
input
. fields
. keys ( )
. flat_map ( | p | p . neighbors ( ) )
. map ( | pos | {
let cell = readonly . get ( pos ) ;
let new = match ( & cell , count_live_neighbors ( & pos , & readonly ) ) {
( Cell ::Alive , 2 ..= 3 ) = > Cell ::Alive ,
( Cell ::Dead , 3 ) = > Cell ::Alive ,
_ = > Cell ::Dead ,
} ;
( pos , new )
} )
. collect ( )
2020-12-17 14:04:05 +01:00
}
fn part1 ( parsed : & Parsed ) -> usize {
let mut clone = parsed . clone ( ) ;
for _ in 0 .. 6 {
clone = make_step ( clone ) ;
}
clone . fields . into_iter ( ) . filter ( | ( _ , c ) | c = = & Cell ::Alive ) . count ( )
}
fn part2 ( parsed : & Parsed ) -> usize {
unimplemented! ( )
}
fn main ( ) {
let input = parse_input ( & read_input ( ) ) ;
println! ( " Part 1: {} " , part1 ( & input ) ) ;
println! ( " Part 2: {} " , part2 ( & input ) ) ;
}
#[ cfg(test) ]
mod tests {
use super ::* ;
use aoc2020 ::* ;
use paste ::paste ;
use test ::black_box ;
const TEST_INPUT : & str = " .#.
.. #
###" ;
test! ( part1 ( ) = = 112 ) ;
//test!(part2() == 0);
bench! ( part1 ( ) = = 348 ) ;
//bench!(part2() == 0);
// bench_input!(fields == 0);
}